通过网络流套接字发送byte []数据。 C#

时间:2016-10-24 04:16:14

标签: c# sockets networkstream

我想通过网络流发送字符串json。客户端的代码

 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是byte [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是byte [988324]

但我收到的byData与我发送的jsonbytes不同。

我需要一些帮助。

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

1 个答案:

答案 0 :(得分: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);
    }

这可以接收大量数据,并且与发送者的长度无关。

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