2016-10-24 120 views
0

我想通过网络流发送字符串json。在客户端代码通过网络流套接字发送byte []数据。 c#

using (var ns = new NetworkStream(socket)) 
{ 
string json = JsonConvert.SerializeObject(listCfile, Formatting.Indented); 
byte[] jsonbytes = Encoding.UTF8.GetBytes(json); 
byte[] jsonLength = BitConverter.GetBytes(jsonbytes.Length); 
ns.Write(jsonLength, 0, jsonLength.Length); 
ns.Write(jsonbytes, 0, jsonbytes.Length); 
} 

jsonbytes是字节[988324]

在服务器侧

using (var ns = new NetworkStream(socket)) 
{ 
byte[] byDataLength = new byte[4]; 
ns.Read(byDataLength, 0, 4); 
int jsonLength = BitConverter.ToInt32(byDataLength, 0); 
byte[] byData = new byte[jsonLength]; 
ns.Read(byData, 0, jsonLength); 
File.WriteAllBytes("E:\\json.txt",byData); 
} 

byData是[988324]

但是byData我接收到的字节是不是相同jsonbytes我发送。

我需要一些帮助。

更新!有时它工作。收到的ByData与我发送的jsonbytes相同 有些时候它不起作用:(

+0

“它丢失了一些数据”不是对问题有帮助的描述。请详细说明。 –

+0

从客户端发送jsonLength之前发送的实际数据,在服务器端建立一个缓冲区来接收json数据? – nura

+0

@nura我认为你一样,但我是初学者在C#和编码,所以你可以给我一些例子,非常感谢。 – vmphuong

回答

0

您可以尝试使用原始套接字发送和接收以及使用存储流和未知数据长度的数据包结束机制。

下面是使用原始套接字和缓冲在存储器中的数据流示出的方法的一个片段,直到结束数据包被检测。

protected const int SIZE_RECEIVE_BUFFER = 1024; /// Receive buffer size 
    protected const string EOF = "!#~*|"; /// End of packet string 
    MemoryStream _msPacket = new MemoryStream(); /// Memory stream holding buffered data packets 
    int _delmtPtr = 0; /// Ranking pointer to check for EOF 
    Socket _baseSocket; 
    public event EventHandler OnReceived; 

    // TODO: - 
    // Add methods to connect or accept connections. 
    // When data is send to receiver, send with the same EOF defined above. 
    // 
    // 
    public void RegisterToReceive() 
    { 
     byte[] ReceiveBuffer = new byte[SIZE_RECEIVE_BUFFER]; 
     _baseSocket.BeginReceive 
     (
      ReceiveBuffer, 
      0, 
      ReceiveBuffer.Length, 
      SocketFlags.None, 
      new AsyncCallback(onReceiveData), 
      ReceiveBuffer 
     ); 
    } 
    private void onReceiveData(IAsyncResult async) 
    { 
     try 
     { 
      byte[] buffer = (byte[])async.AsyncState; 
      int bytesCtr = 0; 
      try 
      { 
       if (_baseSocket != null) 
        bytesCtr = _baseSocket.EndReceive(async); 
      } 
      catch { } 
      if (bytesCtr > 0) 
       processReceivedData(buffer, bytesCtr); 
      RegisterToReceive(); 
     } 
     catch{ } 
    } 

    private void processReceivedData(byte[] buffer, int bufferLength) 
    { 
     byte[] eof = Encoding.UTF8.GetBytes(EOF); 
     int packetStart = 0; 
     for (int i = 0; i < bufferLength; i++) 
     { 
      if (buffer[i].Equals(eof[_delmtPtr])) 
      { 
       _delmtPtr++; 
       if (_delmtPtr == eof.Length) 
       { 
        var lenToWrite = i - packetStart - (_delmtPtr - 1); 
        byte[] packet = new byte[lenToWrite + (int)_msPacket.Position]; 

        if (lenToWrite > 0) 
         _msPacket.Write(buffer, packetStart, lenToWrite); 

        packetStart = i + 1; 
        _msPacket.Position = 0; 
        _msPacket.Read(packet, 0, packet.Length); 

        try 
        { 
         if (OnReceived != null) 
          OnReceived(packet, EventArgs.Empty); 
        } 
        catch { } 
        _msPacket.Position = 0; 
        _delmtPtr = 0; 
       } 
      } 
      else 
      { _delmtPtr = 0; } 
     } 
     if (packetStart < bufferLength) 
      _msPacket.Write(buffer, packetStart, bufferLength - packetStart); 
     if (_msPacket.Position == 0) 
      _msPacket.SetLength(0); 
    } 

这可以接收大的长度的数据,并且独立长度的由发件人发送。

上面的方法显示了如何仅接收数据,因此必须在原始套接字上包含其他连接,接受,发送数据等方法。

+0

非常感谢你,但对我来说太复杂了。还有其他方法可以做到这一点。我的数据长度不是未知的。 – vmphuong

相关问题