简体   繁体   English

c#中的Winsock服务器/客户端应用程序

[英]Winsock server/client application in c#

I'm working to make a Client/Server Application in C# using winsock Control.我正在使用 winsock Control 在 C# 中制作客户端/服务器应用程序。 I done every thing in that but i stuck the place of sending data from client to server.我做了所有的事情,但我坚持将数据从客户端发送到服务器的地方。 In my program server always listen the client using the ip and port.在我的程序中,服务器总是使用 ip 和端口监听客户端。 I send the data from the client to server.我将数据从客户端发送到服务器。

1)When click the Listen button on the server form it open the server where client is connect. 1)当单击服务器窗体上的侦听按钮时,它会打开客户端连接的服务器。

2)In Client form 1st i click the connect button for that the server is connected Gives an message (Connect Event: ip) for this message we easly know that the client is connected to the server. 2)在客户端表单 1 中,我单击连接按钮,服务器已连接 为该消息提供消息(连接事件:ip),我们很容易知道客户端已连接到服务器。

3)Then we enter some data in the Send Data text Box then click Send Button to send the data to server and also save in client. 3)然后我们在发送数据文本框中输入一些数据,然后单击发送按钮将数据发送到服务器并保存在客户端。

Code Below:代码如下:

SERVER:服务器:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;

namespace Server
{
    public partial class Form1 : Form
    {      
        public Form1()
        {
            InitializeComponent();        
        }
        const string DEFAULT_SERVER = "ip";
        const int DEFAULT_PORT = 120;

        System.Net.Sockets.Socket serverSocket;
        System.Net.Sockets.SocketInformation serverSocketInfo;

        public string Startup()
        {               
            IPHostEntry hostInfo = Dns.GetHostByName(DEFAULT_SERVER);
            IPAddress serverAddr = hostInfo.AddressList[0];
            var serverEndPoint = new IPEndPoint(serverAddr, DEFAULT_PORT);            
            serverSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
            serverSocket.Bind(serverEndPoint);

            return serverSocket.LocalEndPoint.ToString();    
        }

        public string Listen()
        {
            int backlog = 0;
            try
            {
                serverSocket.Listen(backlog);
                return "Server listening";
            }
            catch (Exception ex)
            {
                return "Failed to listen" + ex.ToString();
            }
        }
        public string ReceiveData()
        {
            System.Net.Sockets.Socket receiveSocket;

            byte[] buffer = new byte[256];

            receiveSocket = serverSocket.Accept();

            var bytesrecd = receiveSocket.Receive(buffer);

            receiveSocket.Close();

            System.Text.Encoding encoding = System.Text.Encoding.UTF8;

            return encoding.GetString(buffer);
        }           

        private void Listen_Click(object sender, EventArgs e)
        {
            string serverInfo = Startup();
            textBox1.Text = "Server started at:" + serverInfo;

            serverInfo = Listen();
            textBox1.Text = serverInfo;

            //string datatosend = Console.ReadLine();
            //SendData(datatosend);

            serverInfo = ReceiveData();
            textBox1.Text = serverInfo;

            //Console.ReadLine();
        }

        private void winsock_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e)
        {
            ReceiveData();
            Listen();
        }

        private void winsock_ConnectEvent(object sender, EventArgs e)
        {
            Listen();
        }
    }
}

This all are work perfectly But here my problem is that i get data form the client to server at only one time.这一切都完美无缺但在这里我的问题是我只一次从客户端获取数据到服务器。 When i send data again from the client to the server its not working and gives me some Message like当我再次从客户端向服务器发送数据时,它不工作并给了我一些类似的消息

Additional information: Only one usage of each socket address (protocol/network address/port) is normally permitted附加信息:通常每个套接字地址(协议/网络地址/端口)只允许使用一次

In the server form在服务器形式

serverSocket.Bind(serverEndPoint);

Please someone help me to solve my problem.请有人帮我解决我的问题。

Thank you.谢谢你。

Try this.尝试这个。 It helps you它可以帮助你

 delegate void AddTextCallback(string text);

        public Form1()
        {
            InitializeComponent();
        }
        private void ButtonConnected_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(ServerHandler));
        }

        private void ServerHandler(object state)
        {
            TcpListener _listner = new TcpListener(IPAddress.Parse("12.2.54.658"), 145);

            _listner.Start();

            AddText("Server started - Listening on port 145");

            Socket _sock = _listner.AcceptSocket();

            //AddText("User from IP " + _sock.RemoteEndPoint);

            while (_sock.Connected)
            {
                byte[] _Buffer = new byte[1024];

                int _DataReceived = _sock.Receive(_Buffer);

                if (_DataReceived == 0)
                {
                    break;
                }

                AddText("Message Received...");

                string _Message = Encoding.ASCII.GetString(_Buffer);

                AddText(_Message);
            }

            _sock.Close();
            AddText("Client Disconnected.");

            _listner.Stop();
            AddText("Server Stop.");
        }

        private void AddText(string text)
        {
            if (this.listBox1.InvokeRequired)
            {
                AddTextCallback d = new AddTextCallback(AddText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.listBox1.Items.Add(text);
            }
        }

I'm also have the same problem like you on last month but i solve that using this http://stackoverflow.com/questions/21072100/receive-multiple-different-messages-tcp-listner-c-sharp from stackoverflow.我上个月也有和你一样的问题,但我使用来自 stackoverflow 的http://stackoverflow.com/questions/21072100/receive-multiple-different-messages-tcp-listner-c-sharp解决了这个问题。 This helps me lot hope it helps to solve your problem also.这对我很有帮助,希望它也有助于解决您的问题。

I'm not 100% sure you understand TCP sockets so here goes.我不是 100% 确定你了解 TCP 套接字,所以这里是。

When you use a TCP listener socket you first bind to a port so that clients have a fixed, known point to connect to.当您使用 TCP 侦听器套接字时,您首先绑定到一个端口,以便客户端有一个固定的、已知的连接点。 This reserves the port for your socket until you give it up by calling Close() on that socket.这会为您的套接字保留端口,直到您通过对该套接字调用Close()放弃它。

Next you Listen in order to begin the process of accepting clients on the port you bound to.接下来,您侦听以开始在您绑定到的端口上接受客户端的过程。 You can do both this and the first step in one but as you haven't I haven't here.你可以同时做这件事和第一步,但因为你没有,我没有在这里。

Next you call Accept() .接下来调用Accept() This blocks (halts execution) until a client connects and then it returns a socket which is dedicated to communication with that client.这会阻塞(停止执行),直到客户端连接,然后它返回一个专用于与该客户端通信的套接字。 If you want to allow another client to connect, you have to call Accept() again.如果要允许另一个客户端连接,则必须再次调用Accept()

You can then communicate with your client using the socket that was returned by Accept() until you're done, at which point you call Close() on that socket.然后,您可以使用Accept()返回的套接字与客户端进行通信,直到完成为止,此时您可以对该套接字调用Close()

When you're done listening for new connections you call Close() on your listener socket.当您完成侦听新连接时,您在侦听器套接字上调用Close()


However when you press your listen button the following happens:但是,当您按下收听按钮时,会发生以下情况:

You bind correctly, you begin listening correctly and then your call to ReceiveData() blocks on the Accept call until a client is received.您正确绑定,开始正确收听,然后您对ReceiveData()的调用在 Accept 调用上阻塞,直到收到客户端。 You then receive some data (though this is TCP so that might not be the whole data!) and then you instantly close the connection to your client.然后您会收到一些数据(尽管这是 TCP,因此可能不是全部数据!)然后您立即关闭与客户端的连接。

I presume to get the error you're getting you must then press listen again on your server.我想你会得到你得到的错误,然后你必须在你的服务器上再次按下监听。 This therefore restarts the whole listener socket and when you get to bind to the port the second time your previous listener is still bound to it and thus the call fails because something's already allocated on that port.因此,这将重新启动整个侦听器套接字,当您第二次绑定到该端口时,您的前一个侦听器仍然绑定到它,因此调用失败,因为该端口上已经分配了某些内容。


Solution wise you need to keep the socket returned from the Accept() call open until you're done with it.明智的解决方案是,您需要保持从Accept()调用返回的套接字打开,直到完成它。 Have the client handle the close by calling the Shutdown() method on their socket or establish some convention for marking the end of communication.让客户端通过在其套接字上调用Shutdown()方法来处理关闭,或者建立一些约定来标记通信结束。

You're also going to run into trouble when you try and have multiple users connected and so at some point you're either going to require threads or some asynchronous sockets but I feel that's out the scope of this question.当您尝试连接多个用户时,您也会遇到麻烦,因此在某些时候您要么需要线程,要么需要一些异步套接字,但我觉得这超出了这个问题的范围。

我建议你不要使用 AxMSWinsockLib .. 看看这里给出的套接字示例,它显示了如何创建客户端套接字和服务器套接字 - https://msdn.microsoft.com/en-us/library/kb5kfec7(v= vs.110).aspx和这个 - https://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM