【问题标题】:C# Socket.Receive() data is out of order & Truncated at the beginning & at EndC# Socket.Receive() 数据无序并在开头和结尾截断
【发布时间】:2021-09-30 16:02:49
【问题描述】:

我并尝试在 Windows 上的 C# (DotNET 4.7.2) 中同时创建 TCPServer 和 TCPClient。 从客户端我通过连续 4 次调用 Socket.Send() 发送数据,并且这 4 个连续发送一起循环。 在服务器端,我通过循环接收数据,直到数据可用并在循环内打印 控制台上的每个字节数组。

现在是我的疑问:-

  1. 有时数据出现乱序(不是按照我在客户端调用 Socket.Send() 的顺序)。

  2. 开头和结尾的数据被截断。现在人们可能会说,首先我需要收集所有字节,在接收循环完成后,我应该将它连接起来并打印,正确,我明白了。但是第一个初始字节本身丢失了,然后呢?无论我以何种方式打印,第一个字节都应该始终相同,但初始字节本身会被截断

  3. SocketFlags 对此有何影响,尤其是部分标志?

  4. 路由会影响这个吗?

  5. 连续调用发送和一次发送的区别? TCP 是否在协议级别以不同方式处理这两种情况,或者它在低协议级别以何种方式处理连续发送?

  6. 是否有可能第二个 Send() 方法调用数据在第一个 send() 方法调用之前到达,在连续的 send 方法调用中?

我是套接字编程的新手。

我还附上了输出截图。在截图中看黄色标记的文本。

console ScreenShot1

console Screenshot2

console screenshot3

我的代码在这里:-

这是客户端代码

    static void Main(string[] args)
    {
        Console.WriteLine("press any key to start");
        Console.ReadLine();

        byte[] data = Encoding.ASCII.GetBytes("@123456789@");
        byte[] data2 = Encoding.ASCII.GetBytes("&.RAJA.BHOJ.&");
        byte[] data3 = Encoding.ASCII.GetBytes("#abcdefghi#");
        byte[] data4 = Encoding.ASCII.GetBytes("/ABCDEFGHI/");

        Socket s = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        s.Connect(ipEnd);

    mark1:
        
        int x = s.Send(data);
            x = s.Send(data2);
            x = s.Send(data3);
            x = s.Send(data4);            

        goto mark1;
   }

这是服务器端代码

    static void Main(string[] args)
    {
        byte[] Bytes = new byte[50];
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, protocolType.Tcp);
        listener.Bind(ipEnd);
        listener.Listen(100);

        Socket handler = listener.Accept();
    mark1:
        
        while(handler.Available != 0)
        {
            int byteCount = handler.Receive(Bytes);
            string text = System.Text.Encoding.ASCII.GetString(Bytes);
            Console.WriteLine("received data is :: " + text);
        }     
        
        goto mark1;
    }

【问题讨论】:

    标签: c# .net visual-studio sockets network-programming


    【解决方案1】:

    数据永远不应该乱序,但是:检查.Available 通常是错误的——幸运的是,在这种情况下它并不重要,因为你的goto 基本上使它成为一个热循环。实际上,您通常应该循环直到 byteCount 为非正数(除非您正在执行零长度读取,而您不是)。但是:您没有应用任何框架。在 TCP 中,读取与写入不匹配 1:1;它是一个流协议,只提供“以正确顺序的正确字节,或死套接字”——它对消息没有任何作用。因此,由协议定义一些用于拆分消息的机制。对于文本协议,某种类型的行尾是常见的,或者是诸如nul(字节零)之类的非打印保留字符之类的标记字节。您的代码将负责找到这些标记并正确拆分输入数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-19
      • 2016-08-19
      • 1970-01-01
      • 2016-06-28
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      相关资源
      最近更新 更多