c# socket send data mismatch server data

依然范特西╮ 提交于 2019-12-07 22:59:04

问题


while sending byte[] data via socket (a/sync) i'm getting on messagereceived event mismatch data. For example like this

client:

2013-05-20 12:03:09.6929|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:09.8619|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.0249|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.1899|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.3459|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.5220|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.6890|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:10.8630|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.0490|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.2040|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.3680|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.5340|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.7030|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:11.8600|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!
2013-05-20 12:03:12.0340|DEBUG|Tcp|SendAsync_Completed: Sent ( ; T A , 59 84 65 13 10  ) to 127.0.0.1:10002 (Table)!

server:

2013-05-20 12:03:09.6819|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:09.8959|DEBUG|Table|TableServer.Cmd = ; T A ; T
2013-05-20 12:03:10.0799|DEBUG|Table|TableServer.Cmd = A ; T A
2013-05-20 12:03:10.2569|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:10.4750|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:10.6600|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:10.8830|DEBUG|Table|TableServer.Cmd = ; T A ; T
2013-05-20 12:03:11.0790|DEBUG|Table|TableServer.Cmd = A ; T A
2013-05-20 12:03:11.2700|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:11.5090|DEBUG|Table|TableServer.Cmd = ; T A
2013-05-20 12:03:11.7120|DEBUG|Table|TableServer.Cmd = ; T A ; T
2013-05-20 12:03:11.9180|DEBUG|Table|TableServer.Cmd = A ; T A
2013-05-20 12:03:12.1000|DEBUG|Table|TableServer.Cmd = ; T A

I have tried everything. Switching from async to sync send, thread sleep before send, but nothing works...


回答1:


Please see http://tiny.cc/io, in particular the "Network packets: what you send is not (usually) what you get". It looks like you are expecting to write as per:

var blob = new byte[] {59,84,65,13,10};
for(int i = 0 ; i < 10 ; i++)
    network.Write(blob, 0, blob.Length);

and then have it read as 10 blocks of 5. However, that simply doesn't work: TCP is a stream. When you call Read, you will get "some data, at least one byte or EOF, and at most {count} bytes". The protocol does know not and cannot know how the send code was structured. It could have been buffered at sourse, or not. Packets could be combined and split. All that is guaranteed is that you get the same bytes, in the same order. But not necessarily in the same chunks.

So basically: it is your job to separate the messages. In this case, it looks like you could do that by reading to the sentinel value of 13,10. At the most basic level, that could be something like:

    byte[] ReadToNewline()
    {
        var ms = new MemoryStream();
        int val;
        do
        {
            val = netStream.ReadByte();
            if (val < 0) throw EOF();
            if (val == '\r')
            {
                val = netStream.ReadByte();
                if (val == '\n') return ms.ToArray();
                throw new InvalidOperationException("Expected end-of-line");
            }
            ms.WriteByte((byte)val);
        } while (true);
    }

More elegant solutions are possible; I simply took that from SimpleRedis. You might prefer to read larger buffers locally and just loop through the received buffer looking for the CR/LF pair - noting that the CR could be at the end of one "read", with the LF at the start of another, etc.



来源:https://stackoverflow.com/questions/16647847/c-sharp-socket-send-data-mismatch-server-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!