2014-02-28 115 views
1

在我的客户端/服务器应用程序中,我的客户端将与服务器通信以实现2个功能:客户端将请求服务器的数据,或者它将发送数据以便服务器保存它。我为这两种方法使用了一个套接字,并且要使用的方法由发送的第一个字节定义。如果第一个字节是“1”,它正在请求数据。如果它是“2”,它将发送数据(数据字节在“2”字节后发送)。它非常适合发送数据。但是当我请求数据的时候,只要我不读取客户端的套接字流。这就好像我在发送数据后让客户端读取数据一样,服务器将没有数据可读,并且在尝试读取数据时只会崩溃。C#套接字:写入套接字后无法读取

这里是我的服务器代码:

private const int BufferSize = 1024; 
NetworkStream netstream = null; 
byte[] RecData = new byte[BufferSize]; 
int RecBytes; 

try { 
    netstream = clientSocket.GetStream(); 
    int totalrecbytes = 0; 

    using (MemoryStream ms = new MemoryStream()) { 
     //When I get here, there is no data to read 
     while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) { 
      ms.Write(RecData, 0, RecBytes); 
      totalrecbytes += RecBytes; 
     } 

     byte[] bytes = ms.ToArray(); 
     byte b = bytes[0]; 

     switch (b) { 
      case 1: 

      //Here I gather data and put it in "stream" variable 


      byte[] SendingBuffer = null; 
      int NoOfPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(stream.Length)/Convert.ToDouble(BufferSize))); 
      int TotalLength = (int)stream.Length, CurrentPacketLength, counter = 0; 
      for (int i = 0; i < NoOfPackets; i++) { 
       if (TotalLength > BufferSize) { 
        CurrentPacketLength = BufferSize; 
        TotalLength = TotalLength - CurrentPacketLength; 
       } 
       else 
        CurrentPacketLength = TotalLength; 
       SendingBuffer = new byte[CurrentPacketLength]; 
       stream.Read(SendingBuffer, 0, CurrentPacketLength); 
       netstream.Write(SendingBuffer, 0, (int)SendingBuffer.Length); 
      } 
      netstream.Flush(); 


     } 
     catch (Exception e) { 
      Console.WriteLine("EXCEPTION:\n" + e.ToString()); 
     } 

     break; 
    case 2:    
     //Code to read data 

     break; 
    } 
} 
netstream.Close() 
clientSocket.Close(); 

这里是我的客户端代码:

using (System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient()) { 

    string returnData = ""; 

    IAsyncResult ar = clientSocket.BeginConnect("127.0.0.1", 8080, null, null); 
    System.Threading.WaitHandle wh = ar.AsyncWaitHandle; 
    try { 
     if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false)) { 
      clientSocket.Close(); 
      Console.WriteLine("Timeout"); 
      return; 
     } 

     System.Net.Sockets.NetworkStream serverStream = clientSocket.GetStream(); 

     byte b = 1; 

     byte[] outStream = { b }; 
     serverStream.Write(outStream, 0, outStream.Length); 
     serverStream.Flush(); 

     //If I comment following lines, the server can read sent data, but server can't otherwise 
     byte[] RecData = new byte[1024]; 
     int RecBytes; 
     int totalrecbytes = 0; 
     MemoryStream MS = new MemoryStream(); 
     while ((RecBytes = serverStream.Read(RecData, 0, RecData.Length)) > 0) { 
      MS.Write(RecData, 0, RecBytes); 
      totalrecbytes += RecBytes; 
     } 
     serverStream.Close(); 
     clientSocket.Close(); 
     clientSocket.EndConnect(ar); 

    } 
    catch (Exception ex) { 
     Console.WriteLine("Exceção: " + ex.ToString()); 
    } 
    finally { 
     wh.Close(); 
    } 
} 

所以,我怎样才能将数据发送到服务器,并读取响应? (我甚至试图在发送数据后让线程进入睡眠状态,但没有运气。) 提前致谢。

编辑: 随着一些调试消息,我发现服务器读取发送的“1”字节,但不知何故它被卡在while循环内,就像服务器刚刚停在那里,没有更多的循环,它不会离开while循环。我在while循环中的控制台中写入“loop”之后,并在控制台中写入了读取字节。它写了一次“循环”和读取的字节。

回答

1

此代码让我担心:

 //When I get here, there is no data to read 
    while ((RecBytes = netstream.Read(RecData, 0, RecData.Length)) > 0) { 
     ms.Write(RecData, 0, RecBytes); 
     totalrecbytes += RecBytes; 
    } 

您正在阅读,直到客户端关闭连接(或关闭发送,你不这样做)。但客户端只在服务器回复时关闭。服务器的答复永远不会到来。这是一个僵局。

解决方案:读取单个字节以确定请求命令(b)。

与这个问题无关,您的“封包”发送(NoOfPackets,...)似乎不起任何作用。只需使用Stream.Copy即可。 TCP没有数据包。

更好的解决方案是放弃您的自定义TCP协议并使用HTTP库。所有这些担忧都会消失。代码中存在各种小问题,这在TCP代码中很常见。

+0

看来你是对的。要测试它。 – user1531978

+0

完美。就是这样。谢谢。 – user1531978