现象
用HttpWebReques,WebClient在抓包和Web下数据正常,但是去向某个硬件后台发起POST请求时,Body会为空。就算设置Expect100Continue和Connetion也无法解决问题。
后台断点展示:
正常的数据包,有正常内容
C#的POST,缺失Body内容
分析
在长时间的Debug和测试后,排除了报文格式和属性设置,编码的问题。
查阅资料和百度搜索,得知c# 的http去post和get是专门为Windows设计的,某些服务器,单片机后台,可能可能无法解析,设置的Content-Length可能无效,但正常访问抓包ok,设置Expect100Continue也会无效。程序跑起来有一半多时候会出错,还有其他的一些问题。
解决方法
弃用HttpWebReques,WebClient,HttpClient等类库方法。改用TCPClient去模拟HTTP去向服务器后台POST完整数据。
通过解析URL,然后拿到URL的IP地址和端口,然后建立一个TCP连接,再把要post的东西send过去即可。
post得到的东西可以用一个自建的类存储来,再去读取调用。
前辈已经造好的轮子!拿去用就好!
出处:C# 使用TcpClient模拟HTTP请求的使用_HOT星辰的博客-CSDN博客
public static Response HTTP(string _url, string _type, string _postdata, string _cookie, Encoding _responseEncode)
{
try
{
TcpClient clientSocket = new TcpClient();
Uri URI = new Uri(_url);
clientSocket.Connect(URI.Host, URI.Port);
StringBuilder RequestHeaders = new StringBuilder();
RequestHeaders.Append(_type + " " + URI.PathAndQuery + " HTTP/1.1\r\n");
RequestHeaders.Append("Content-Type: application/x-www-form-urlencoded\r\n");
RequestHeaders.Append("User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11\r\n");
RequestHeaders.Append("Cookie: " + _cookie + "\r\n");
RequestHeaders.Append("Accept: */*\r\n");
RequestHeaders.Append("Host: " + URI.Host + "\r\n");
RequestHeaders.Append("Content-Length: " + _postdata.Length + "\r\n");
RequestHeaders.Append("Connection: close\r\n\r\n");
byte[] request = Encoding.UTF8.GetBytes(RequestHeaders.ToString() + _postdata);
clientSocket.Client.Send(request);
byte[] responseByte = new byte[1024000];
int len = clientSocket.Client.Receive(responseByte);
string result = Encoding.UTF8.GetString(responseByte, 0, len);
clientSocket.Close();
int headerIndex = result.IndexOf("\r\n\r\n");
string[] headerStr = result.Substring(0, headerIndex).Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string,string> responseHeader = new Dictionary<string, string>();
for (int i = 0; i < headerStr.Length; i++)
{
string[] temp = headerStr[i].Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries);
if (temp.Length == 2)
{
if (responseHeader.ContainsKey(temp[0]))
{
responseHeader[temp[0]] = temp[1];
}
else
{
responseHeader.Add(temp[0], temp[1]);
}
}
}
Response response = new Response();
response.HTTPResponseHeader = responseHeader;
string[] httpstatus = headerStr[0].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
if (httpstatus.Length > 2)
{
response.HTTPStatusCode = httpstatus[1];
}
else
{
response.HTTPStatusCode = "400";
}
response.HTTPResponseText = _responseEncode.GetString(Encoding.UTF8.GetBytes(result.Substring(headerIndex + 4)));
return response;
}
catch
{
return null;
}
}
}
public class Response
{
string hTTPStatusCode;
///
/// http状态代码
///
public string HTTPStatusCode
{
get { return hTTPStatusCode; }
set { hTTPStatusCode = value; }
}
Dictionary<string, string> hTTPResponseHeader;
///
/// Response的header
///
public Dictionary<string, string> HTTPResponseHeader
{
get { return hTTPResponseHeader; }
set { hTTPResponseHeader = value; }
}
string hTTPResponseText;
///
/// html代码
///
public string HTTPResponseText
{
get { return hTTPResponseText; }
set { hTTPResponseText = value; }
}
}