我目前正在使用内置嵌入式Linux Web服务器的测量设备,可以使用所谓的CGI - LAN接口进行控制。如果想要更改设备的设置,必须首先发送TCP / IP登录数据包,然后发送一个密钥代码来控制指定的功能或接收数据。
通过使用TCP / IP数据包工具,例如Paket Sender,一切正常。从端口80到192.168.0.2(PC)的192.168.0.1(设备)的登录数据包,带有ASCII文本的192.168.0.2(PC)(这些是标准密码和登录名,所以我不会模糊这一点):
GET /cgi-bin/login.cgi?username=long&password=nga HTTP/1.0 \n \n
从设备成功接收并确认,如wireshark协议中所示: Wireshark Screenshot
但与Microsoft提供的Standard C# TCP/IP Client相同的请求会返回错误请求错误消息。有点C#不发送[FIN,ACK]数据包,如#34;数据包发送者"。 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>
Wireshark Screenshot此次沟通。
好吧,我不知道为什么C#没有发送[FIN,ACK]消息。也许有人经历过同样的事情?或者有一个简单的解释?也许我错过了TCP / IP套接字中的一个选项?如果有帮助,我还可以提供Wireshark协议文件。
答案 0 :(得分:1)
我猜服务器要求发送方在发送响应之前发送FIN / ACK ,是吗? FIN意味着关闭该(定向)流,所以如果问题确实是缺少的FIN,我猜测在发送请求之后你需要的是但是< em>在听取响应之前,添加:
sender.Shutdown(SocketShutdown.Send);
应该FIN出站连接。
但是,请参阅Dirk对该问题的评论;它可能只是你没有正确形成一个完整的请求,而且FIN目前让它间接工作。
请注意, 也可能想要设置sender.NoDelay = true;
,但这应该是无关的。