【问题标题】:C#: Trouble with socket ReceiveAsync and SendAsync on Remote HostC#:远程主机上的套接字 ReceiveAsync 和 SendAsync 出现问题
【发布时间】:2013-08-22 18:10:52
【问题描述】:

首先我想说的是,这个带有服务器/客户端的代码在我的 PC 上运行良好(客户端和服务器都在同一台 PC 上运行)

当我在专用服务器上托管服务器时,问题就开始了。我第二次尝试与客户端发送或接收时,客户端将花费大量时间来完成操作(谈论接收 1 个字节的数据需要超过 1 小时!)

** 我可以通过在每次发送/接收命令后再次断开和连接套接字来避免这个问题

我不明白为什么要在同一个连接会话中执行超过 1 个发送/接收操作需要这么多时间。


这是一个例子:

连接服务器:

    RC_Server = new SocketConnection_Client(RC_IpEndPoint);

现在客户端已连接到服务器,我可以正常开始发送/接收了。

我第一次尝试发送或接收它工作完美且快速(不管缓冲区长度)。

    RC_Server.sendCompleted = false;
    RC_Server.Send(buffer); //in this case buffer size is 1024
    while (!RC_Server.sendCompleted) { } //here thread is waiting for the send to complete

现在,如果我想开始与服务器的接收会话

        RC_Server.receiveCompleted = false;
        RC_Server.Receive(buffer.Length); //in this case byffer needs to get 4 bytes from server
        while (!RC_Server.receiveCompleted) { } // <<- Here it will take VERY long time for the operation to complete
        buffer = RC_Server.buffer;

第二个 Receive 操作永远不会到达 socket_receiveCompleted_Completed 事件。


但是.. 如果我在第一次发送/接收会话后关闭与服务器的连接,然后打开与服务器的新连接,然后执行下一个发送/接收会话, 那么一切都会完美无缺。 (并为多次发送/接收多次复制此方法)

同样,我的工作站不会出现此问题(如果我在同一台 PC 上运行服务器和客户端)。只有当我在远程主机上托管服务器时才会发生这种情况。

这是我的 Socket 类的一部分:

    class SocketConnection_Client
    {
        public string errorMsg = string.Empty;
        public bool receiveCompleted = false;
        public bool sendCompleted = false;
        int bytesReceived = 0;
        public byte[] buffer;
        Socket socket;

        public SocketConnection_Client(IPEndPoint ipEP)
        {
            socket = new Socket(ipEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                socket.Connect(ipEP);
            }
            catch (Exception ex)
            {
                errorMsg = ex.Message;
                socket.Dispose();
                socket = null;
            }
        }

        public void Send(byte[] sBuffer)
        {
            buffer = null;
            if (socket == null)
            {
                sendCompleted = true;
                return;
            }
            sendCompleted = false;

            SocketAsyncEventArgs socket_sendCompleted = new SocketAsyncEventArgs();
            socket_sendCompleted.SetBuffer(sBuffer, 0, sBuffer.Length);
            socket_sendCompleted.Completed += socket_sendCompleted_Completed;
            socket.SendAsync(socket_sendCompleted);
        }

        void socket_sendCompleted_Completed(object sender, SocketAsyncEventArgs e)
        {
            sendCompleted = true;
        }

        public void Receive(int bLength)
        {
            bytesReceived = 0;
            buffer = null;
            if (socket == null)
            {
                receiveCompleted = true;
                return;
            }
            receiveCompleted = false;

            buffer = new byte[bLength];
            SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs();
            socket_receiveCompleted.SetBuffer(buffer, 0, buffer.Length);
            socket_receiveCompleted.Completed += socket_receiveCompleted_Completed;
            socket.ReceiveAsync(socket_receiveCompleted);
        }

        private void Receive_Continue()
        {
            SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs();
            socket_receiveCompleted.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived);
            socket_receiveCompleted.Completed += socket_receiveCompleted_Completed;
            socket.ReceiveAsync(socket_receiveCompleted);
        }

        void socket_receiveCompleted_Completed(object sender, SocketAsyncEventArgs e)
        {
            bytesReceived += e.BytesTransferred;
            if (e.BytesTransferred == 0 && bytesReceived == 0)
            {
                socket.Dispose();
                socket = null;
                receiveCompleted = true;
                throw new Exception("Server Disconnected");
            }
            else if (bytesReceived != buffer.Length)
                Receive_Continue();
            else
                receiveCompleted = true;
        }
    }

赞赏。 谢谢。

【问题讨论】:

    标签: c# sockets asyncsocket sendasync


    【解决方案1】:

    您忽略了来自ReceiveAsync 的返回值。注意the documentation -- 有两种可能的行为,你必须检查返回值来区分它们:

    如果 I/O 操作处于挂起状态,则返回 true。 e 参数上的SocketAsyncEventArgs.Completed 事件将在操作完成时引发。

    如果 I/O 操作同步完成,则返回 false。 在这种情况下,e 参数上的SocketAsyncEventArgs.Completed 事件将不会引发,e 对象作为参数传递可以在方法调用返回后立即检查以检索操作结果。

    【讨论】:

      猜你喜欢
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      • 2023-03-27
      • 2022-10-06
      相关资源
      最近更新 更多