Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tcp/Ip C#请求错误/缺少数据包_C#_Sockets_Tcp_Ip - Fatal编程技术网

Tcp/Ip C#请求错误/缺少数据包

Tcp/Ip C#请求错误/缺少数据包,c#,sockets,tcp,ip,C#,Sockets,Tcp,Ip,我目前正在使用一种内置嵌入式Linux web服务器的测量设备,它可以通过所谓的局域网接口进行控制。如果要更改设备的设置,必须首先发送TCP/IP登录数据包,然后发送密钥代码以控制指定功能或接收数据 例如,通过使用TCP/IP数据包工具,一切正常。从192.168.0.2(PC)到端口80的192.168.0.1(设备)的带有ASCII文本的登录数据包(这些是标准密码和登录名,所以我不会混淆): 从设备成功接收并确认,如wireshark协议所示: 但与Microsoft提供的相同请求返回错误

我目前正在使用一种内置嵌入式Linux web服务器的测量设备,它可以通过所谓的局域网接口进行控制。如果要更改设备的设置,必须首先发送TCP/IP登录数据包,然后发送密钥代码以控制指定功能或接收数据

例如,通过使用TCP/IP数据包工具,一切正常。从192.168.0.2(PC)到端口80的192.168.0.1(设备)的带有ASCII文本的登录数据包(这些是标准密码和登录名,所以我不会混淆):

从设备成功接收并确认,如wireshark协议所示:

但与Microsoft提供的相同请求返回错误请求错误消息。有些C#不像“数据包发送方”那样发送[FIN,ACK]数据包。来自Microsoft的修改代码如下所示:

// Data buffer for incoming data.  
        byte[] bytes = new byte[1024];

        // Connect to a remote device.  
        try
        {
            // Establish the remote endpoint for the socket.  
            // This example uses port 11000 on the local computer.  
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 80);

            // Create a TCP/IP  socket.  
            Socket sender = new Socket(IPAddress.Parse("192.168.0.1").AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect the socket to the remote endpoint. Catch any errors.  
            try
            {
                sender.Connect(remoteEP);

                Console.WriteLine("Socket connected to {0}",
                    sender.RemoteEndPoint.ToString());

                // Encode the data string into a byte array.  
                byte[] msg = Encoding.ASCII.GetBytes("GET /cgi-bin/login.cgi?username=long&password=nga HTTP/1.0 \n \n");

                // Send the data through the socket.  
                int bytesSent = sender.Send(msg);

                // Receive the response from the remote device.  
                int bytesRec = sender.Receive(bytes);
                Console.WriteLine("Echoed test = {0}",
                    Encoding.ASCII.GetString(bytes, 0, bytesRec));

                // Release the socket.  
                sender.Shutdown(SocketShutdown.Both);
                sender.Close();

            }
            catch (ArgumentNullException ane)
            {
                Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception : {0}", e.ToString());
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
此代码段的输出:

Socket connected to 192.168.0.1:80
Echoed test = HTTP/1.0 408 Request Timeout
Content-type: text/html
Date: Mon, 26 Mar 2018 16:41:34 GMT
Connection: close

<HTML><HEAD><TITLE>408 Request Timeout</TITLE></HEAD>
<BODY><H1>408 Request Timeout</H1>
No request appeared within 60 seconds
</BODY></HTML>
连接到192.168.0.1:80的插座
回声测试=HTTP/1.0 408请求超时
内容类型:text/html
日期:2018年3月26日星期一格林尼治标准时间16:41:34
连接:关闭
408请求超时
408请求超时
60秒内未出现任何请求
这封信的内容


嗯,我不知道,为什么C#不发送[FIN,ACK]消息。也许有人也有过同样的经历?还是有一个简单的解释?也许我在TCP/IP套接字中缺少一个选项?如果有帮助,我还可以提供Wireshark协议文件

我猜服务器要求发送方在发送响应之前发送FIN/ACK,是吗?FIN意味着关闭(定向)流,因此如果问题真的是缺少FIN,我猜您需要在发送请求后但在侦听响应之前添加:

sender.Shutdown(SocketShutdown.Send);
应该为出站连接提供FIN

然而,另见德克对该问题的评论;这可能只是因为您没有正确地形成完整的请求,而FIN目前正在间接地使其工作


请注意,您可能还需要设置
sender.NoDelay=true,尽管这应该是不相关的。

GET请求不应该以
\r\n\r\n
结尾吗?TCP存在已知(自1970年代以来)竞争条件。不同的供应商允许TCP以不同的方式工作,因此您可能会发现供应商软件之间的差异。问题之一是当服务器和客户端同时尝试关闭连接时。可能无法发送FIN ACK。您应该始终只打开和关闭客户端(而不是服务器)的连接。您是否注意到60秒间隔的超时?看起来服务器试图与客户端建立http连接,但客户端没有响应,因此服务器关闭了连接。@Dirk不幸的是,这并不能解决问题。
sender.Shutdown(SocketShutdown.Send);