2016-10-24 7 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は、サーバ側

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はバイト[98​​8324]

だったが、私は受け取ったbyDataは同じではありませんで、バイト[98​​8324]

ましたjsonbytesが送った。

私はいくつかの助けが必要です。

更新!時にはそれは動作します。受信したデータは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

関連する問題