2016-10-24 7 views
0

Я хочу отправить строку json поверх сетевого потока. код на стороне клиентаотправлять байт [] данные по сетевому потоку. 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 i sent Несколько раз это не работает :(

+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

 Смежные вопросы

  • Нет связанных вопросов^_^