时间:2019-05-17 标签:c#socket发送数据与服务器数据不匹配

标签 c# tcpclient

通过套接字(a/sync)发送字节[]数据时,我收到消息接收事件不匹配数据。比如像这样

客户:

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)!

服务器:

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

我已经尝试了一切。从异步发送切换到同步发送,发送前线程休眠,但没有任何效果...

最佳答案

请参阅http://tiny.cc/io ,特别是“网络数据包:您发送的内容(通常)不是您收到的内容”。看来您希望按照以下方式编写:

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

然后将其读取为 10 个 block ,每 block 5 个。但是,这根本行不通:TCP 是一个流。当你调用Read时,你会得到“一些数据,至少一个字节或EOF,最多{count}个字节”。协议(protocol)不知道也不可能知道发送代码的结构。它可能在源头被缓冲,也可能没有。数据包可以合并和拆分。所保证的是您以相同的顺序获得相同的字节。但不一定在相同的 block 中。

所以基本上:分离消息是你的工作。在本例中,您似乎可以通过读取 1310 的哨兵值来做到这一点。在最基本的层面上,这可能是这样的:

    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);
    }

更优雅的解决方案是可能的;我只是从 SimpleRedis 中获取的。您可能更喜欢在本地读取较大的缓冲区,然后循环遍历接收到的缓冲区以查找 CR/LF 对 - 请注意,CR 可能位于一个“读取”的末尾,而 LF 可能位于另一个“读取”的开头,等等。

关于时间:2019-05-17 标签:c#socket发送数据与服务器数据不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16647847/

相关文章:

c# - "IOException:invalid stream header: 00010000"在 TCP 上从 C# 主机向 Java 客户端获取数据时

c# - 从 MVC 5 下载文件到 Angular 2

c# - 关于点云数据结构的建议

java - 使用 Java 和 Dynamic C 通过 WiFi 进行套接字连接

c# - 管理 TcpClient 连接

c# - 是否需要同时关闭 NetworkStream 和 TcpClient,或者只关闭 TcpClient?

c# - 异步组件和 WinForms

c# - 为什么我的线程安全字典实现会产生数据竞争?

c# - 在 Parallel.For 中修改方法局部变量。这有多线程安全?

c# - LINQ to Entities 无法识别方法 'System.String[] ToArray[String]