在服务器中读取 byte[] 的异步套接字问题

问题描述

我的简单异步套接字应用程序有问题。

有时,在我的服务器的 BeginReceive 回调期间,我无法读取客户端发送的所有数据。

我在服务器中的代码

 public void ReadCallback(IAsyncResult ar) {
     StateObject state = (StateObject)ar.AsyncState;
     Socket handler = state.workSocket;
     int bytesRead = handler.EndReceive(ar);
     if (bytesRead > 0) {
        Buffer.Blockcopy(state.buffer,state.ImageBuffer,state.TotBytesRead,bytesRead);
        state.TotBytesRead += bytesRead;
        if (state.TotBytesRead < state.ImageSize)
           handler.BeginReceive(state.buffer,StateObject.BufferSize,new AsyncCallback(ReadCallback),state);
        else { // #1
           var result = this.OnDataReceived?.Invoke(this,new MemoryNetworkArgs(new MemoryStream(state.ImageBuffer),handler.RemoteEndPoint.ToString(),null,handler));
           Debug.WriteLine(result + " Received...");
           this.AnswerToClient(handler,result);
        }
     }        
  }

我的问题是有时 #1 没有执行,客户端保持锁定等待,因为服务器无法回答(#1)。

我的客户简单代码

IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[1];
        IPEndPoint remoteEP = new IPEndPoint(ipAddress,port);

        // Create a TCP/IP socket.  
        Socket client = new Socket(ipAddress.AddressFamily,SocketType.Stream,ProtocolType.Tcp);

        // Connect to the remote endpoint.  
        client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallback),client);
        connectDone.WaitOne();

        // Send test data to the remote device.  
        SendImage(client,dataToSent);
        
        sendDone.WaitOne();

        // Receive the response from the remote device.  
        Receive(client);
        receiveDone.WaitOne();

并发送图片

      private static void SendImage(Socket client,byte[] data) {
     byte[] imgBuff = data;
     var length = imgBuff.Length;
     Send(client,BitConverter.GetBytes(length));
     sendDone.WaitOne();
     Send(client,imgBuff);
     sendDone.WaitOne();
  }

      private static void Send(Socket client,byte[] data) {
     // Convert the string data to byte data using ASCII encoding.  
     byte[] byteData = data;

     // Begin sending the data to the remote device.  
     client.BeginSend(byteData,byteData.Length,new AsyncCallback(SendCallback),client);
  }

回调:

 private void SendCallback(IAsyncResult ar) {
     try {
        // Retrieve the socket from the state object.  
        Socket client = (Socket)ar.AsyncState;

        // Complete sending the data to the remote device.  
        int bytesSent = client.EndSend(ar);
        Console.WriteLine("Sent {0} bytes to server.",bytesSent);

        // Signal that all bytes have been sent.  
        sendDone.Set();
     }
     catch (Exception e) {
        Console.WriteLine(e.ToString());
     }
  }

简而言之,客户端首先发送服务器将接收的数据大小,然后发送 byte[] 中的数据,但问题出在数据传输过程中。

服务器读取数据头:

      public void ReadHeaderCallback(IAsyncResult ar) {
     // Retrieve the state object and the handler socket
     // from the asynchronous state object.
     StateObject state = (StateObject)ar.AsyncState;
     Socket handler = state.workSocket;

     // Read data from the client socket. 
     int bytesRead = handler.EndReceive(ar);

     //we need to add error handler here...but later
     state.ImageSize = BitConverter.ToInt32(state.buffer,0);
     state.ImageBuffer = new byte[state.ImageSize];
     state.TotBytesRead= 0;
     handler.BeginReceive(state.buffer,state);
  }

[编辑]

问题可能出在 SendImage 上:

 Send(client,BitConverter.GetBytes(length));
 sendDone.WaitOne();
 Thread.Sleep(2000); // TEST
 Send(client,imgBuff);
 sendDone.WaitOne();

如果我添加睡眠(调试)一切正常,那么在没有服务器应答的情况下进行双重发送的正确方法是什么?或者我需要确认消息? 谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)