2016-10-24 123 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

相關問題