简体   繁体   English

客户端和服务器侦听请求

[英]Clients and Server Listening for requests

I would like to know if my way of thinking is any good. 我想知道我的想法是否有帮助。 Here is sitution: 这里是情况:

  • Server is accepting async for connections. 服务器正在接受异步连接。 After accept is recieveing async on accepted sockets. 接受后在接受的套接字上接收异步。
  • Clients are connecting async to server, then listening for request async. 客户端将异步连接到服务器,然后侦听请求异步。

What I want to do is to send requests from both client and server. 我要做的是从客户端和服务器发送请求。 Other side should recieve it. 另一边应该接受。

Server code: 服务器代码:

    public ServerHandler()
    {
        _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _serverSocket.Bind(_ipLocal);
        _serverSocket.Listen(4);
        _serverSocket.BeginAccept(AcceptCallback, null);
    }

    private void AcceptCallback(IAsyncResult ar)
    {
        Socket socket = (Socket)ar.AsyncState;
        _clients.Add(socket);

        socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, socket);
        _serverSocket.BeginAccept(AcceptCallback, null);
    }

    private void RecieveCallback(IAsyncResult ar)
    {
        var socket = (Socket) ar.AsyncState;
        var recieved = socket.EndReceive(ar);
        var dataBuff = new byte[recieved];

        Array.Copy(_buffer, dataBuff, recieved);

        OnMessageRecieved(dataBuff);

        socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, socket);
    }

    private void Send(byte[] data, Socket socket)
    {
        socket.BeginSend(data, 0, data.Length, SocketFlags.None,
                SendCallback, socket);
    }

    private void SendCallback(IAsyncResult ar)
    {
        var socket = (Socket)ar.AsyncState;
        socket.EndSend(ar);
    }

    private void SendToAll(byte[] data)
    {
        foreach (var clientSocket in _clients)
        {
            Send(data, clientSocket);
            Debug.WriteLine("sent to: " + clientSocket.LocalEndPoint);
        }
    }

Client code: 客户代码:

    public ClientHandler()
    {
        _ipLocal = new IPEndPoint(IPAddress.Parse(ServerIp), Port);
    }

    public void ConnectLoop()
    {
        int attempts = 0;
        while (!_clientSocket.Connected)
        {
            try
            {
                attempts++;
                _clientSocket.BeginConnect(IPAddress.Parse(ServerIp), Port, ConnectCallback, null);
                _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback,
                                           _clientSocket);
            }
            catch (Exception)
            {
                Debug.WriteLine("Connection attempts: " + attempts);
            }
        }

        Debug.WriteLine("Connected");
    }

    private void ConnectCallback(IAsyncResult ar)
    {
        _clientSocket.EndConnect(ar);
    }

    private void RecieveCallback(IAsyncResult ar)
    {
        var socket = (Socket) ar.AsyncState;
        int recieved = _clientSocket.EndReceive(ar);
        var dataBuff = new byte[recieved];

        Array.Copy(_buffer, dataBuff, recieved);

        OnMessageRecieved(dataBuff);

        _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, _clientSocket);
    }

    private void Send(byte[] data, Socket socket)
    {
        socket.BeginSend(data, 0, data.Length, SocketFlags.None,
                SendCallback, socket);
    }

    private void SendCallback(IAsyncResult ar)
    {
        var socket = (Socket)ar.AsyncState;
        socket.EndSend(ar);
    }

Will sth like this work? 某事会喜欢这个作品吗?

EDIT1: Oh, and I want to do it through 1 socket. EDIT1:哦,我想通过1个插座来做。 Client/server sending and recieveing on same socket. 客户端/服务器在同一套接字上发送和接收。 But there can be multiple clients sockets , but only 1 for pair client-server. 但是可以有多个客户端 套接字 ,而一对客户端服务器则只有1个。

Without testing, your code looks alright however, you'll need to provide extra code to determine if you've got a whole message or not. 未经测试,您的代码看起来还不错,但是,您需要提供额外的代码来确定是否收到完整的消息。

When you do a read, you may get one of the following scenarios: 阅读时,您可能会遇到以下情况之一:

  • Some of a message, but not all 一些消息,但不是全部
  • exactly all of a message 完全是一条消息
  • all of a message plus some/all of another message 一条消息的全部加上另一条消息的部分/全部
  • a socket error (disconnected etc). 套接字错误(已断开连接等)。

There are a few generally accepted methods of determining what a whole message is: 有几种普遍接受的确定整个消息是什么的方法:

  • delimiting your message so your receival code needs to look for the delimiters 分隔您的消息,因此您的接收代码需要查找分隔符
  • A fixed message size with some sort of embedding to indicate if there are more messages 固定的消息大小,带有某种形式的嵌入,以指示是否还有更多消息
  • a variable message size but with a fixed "size" part which is transmitted first Ie say the first 4 bytes will indicate the size of the message. 可变的消息大小,但具有固定的“大小”部分,该部分首先发送,即说前4个字节将指示消息的大小。 So you know you always need 4 bytes first to determine the length of the message; 因此,您知道始终总是需要4个字节来确定消息的长度。 and then you know how much to process for the next message. 然后您知道要处理下一条消息的费用。

This SO post Chat service application has some more and links on processing messages. 这个SO post Chat服务应用程序还有更多信息以及处理消息的链接。

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

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