C#:如何使用套接字执行HTTP请求?
我正在尝试使用套接字发出C#:如何使用套接字执行HTTP请求?,c#,sockets,C#,Sockets,我正在尝试使用套接字发出HTTP请求。我的代码如下: using System; using System.Net; using System.Net.Sockets; using System.Text; class test { public static void Main(String[] args) { string hostName = "127.0.0.1"; int hostPort = 9887; int resp
HTTP请求
。我的代码如下:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class test
{
public static void Main(String[] args)
{
string hostName = "127.0.0.1";
int hostPort = 9887;
int response = 0;
IPAddress host = IPAddress.Parse(hostName);
IPEndPoint hostep = new IPEndPoint(host, hostPort);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(hostep);
string request_url = "http://127.0.0.1/register?id=application/vnd-fullphat.test&title=My%20Test%20App";
response = sock.Send(Encoding.UTF8.GetBytes(request_url));
response = sock.Send(Encoding.UTF8.GetBytes("\r\n"));
bytes = sock.Receive(bytesReceived, bytesReceived.Length, 0);
page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes);
Console.WriteLine(page);
sock.Close();
}
}
现在,当我执行上面的代码时,什么都没有发生,而当我在浏览器中输入我的请求\u url
时,我从Snarl收到一个通知,说应用程序已注册
,我从浏览器得到的响应是
SNP/2.0/0/OK/556
我从代码中得到的响应是SNP/3.0/107/BadPacket
那么,我的代码有什么问题
您的请求不正确。根据我们的经验,我们必须看起来像:
string request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\nHost: 127.0.0.1\r\n";
必须在末尾包含内容长度和双新行,以指示标题的结尾
var request = "GET /register?id=application/vnd-fullphat.test&title=My%20Test%20App HTTP/1.1\r\n" +
"Host: 127.0.0.1\r\n" +
"Content-Length: 0\r\n" +
"\r\n";
HTTP 1.1规范可以在这里找到:我对SNP一无所知。您的代码在接收部分有点混乱。我使用下面的示例来发送和读取HTTP GET请求的服务器响应。首先让我们看一下请求,然后检查响应。< /P>
bool flag = true; // just so we know we are still reading
string headerString = ""; // to store header information
int contentLength = 0; // the body length
byte[] bodyBuff = new byte[0]; // to later hold the body content
while (flag)
{
// read the header byte by byte, until \r\n\r\n
byte[] buffer = new byte[1];
socket.Receive(buffer, 0, 1, 0);
headerString += Encoding.ASCII.GetString(buffer);
if (headerString.Contains("\r\n\r\n"))
{
// header is received, parsing content length
// I use regular expressions, but any other method you can think of is ok
Regex reg = new Regex("\\\r\nContent-Length: (.*?)\\\r\n");
Match m = reg.Match(headerString);
contentLength = int.Parse(m.Groups[1].ToString());
flag = false;
// read the body
bodyBuff = new byte[contentLength];
socket.Receive(bodyBuff, 0, contentLength, 0);
}
}
Console.WriteLine("Server Response :");
string body = Encoding.ASCII.GetString(bodyBuff);
Console.WriteLine(body);
socket.Close();
HTTP GET请求:
GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
Accept: text/html
User-Agent: CSharpTests
string - "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n"
服务器HTTP响应头:
HTTP/1.1 200 OK
Date: Sun, 07 Jul 2013 17:13:10 GMT
Server: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16
Last-Modified: Sat, 30 Mar 2013 11:28:59 GMT
ETag: \"ca-4d922b19fd4c0\"
Accept-Ranges: bytes
Content-Length: 202
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
string - "HTTP/1.1 200 OK\r\nDate: Sun, 07 Jul 2013 17:13:10 GMT\r\nServer: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.16\r\nLast-Modified: Sat, 30 Mar 2013 11:28:59 GMT\r\nETag: \"ca-4d922b19fd4c0\"\r\nAccept-Ranges: bytes\r\nContent-Length: 202\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n"
我特意对服务器响应的主体进行了修改,因为我们已经知道它正好是202字节,这是由响应头中的内容长度指定的
查看HTTP规范将发现HTTP头以空的新行(“\r\n\r\n”)结尾。所以我们只需要搜索它
让我们看看一些正在运行的代码。假设变量套接字的类型为System.Net.Sockets.socket
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect("127.0.0.1", 80);
string GETrequest = "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nAccept: text/html\r\nUser-Agent: CSharpTests\r\n\r\n";
socket.Send(Encoding.ASCII.GetBytes(GETrequest));
我们已经将请求发送到服务器,让我们接收并正确解析响应
bool flag = true; // just so we know we are still reading
string headerString = ""; // to store header information
int contentLength = 0; // the body length
byte[] bodyBuff = new byte[0]; // to later hold the body content
while (flag)
{
// read the header byte by byte, until \r\n\r\n
byte[] buffer = new byte[1];
socket.Receive(buffer, 0, 1, 0);
headerString += Encoding.ASCII.GetString(buffer);
if (headerString.Contains("\r\n\r\n"))
{
// header is received, parsing content length
// I use regular expressions, but any other method you can think of is ok
Regex reg = new Regex("\\\r\nContent-Length: (.*?)\\\r\n");
Match m = reg.Match(headerString);
contentLength = int.Parse(m.Groups[1].ToString());
flag = false;
// read the body
bodyBuff = new byte[contentLength];
socket.Receive(bodyBuff, 0, contentLength, 0);
}
}
Console.WriteLine("Server Response :");
string body = Encoding.ASCII.GetString(bodyBuff);
Console.WriteLine(body);
socket.Close();
在C#中,这可能是最糟糕的方法,在.NET中有大量的类来处理HTTP请求和响应,但如果需要,它仍然可以工作。HTTP请求的最低要求是 “GET/HTTP/1.0\r\n\r\n”(如果允许删除主机)。 但在SNARL中,您必须输入内容长度(我最常听到的) 所以
Socket sck=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
连接(ip,端口);
Send(Encoding.UTF8.GetBytes(“HTTP请求头”);
控制台。写入线(“已发送”);
字符串消息=null;
byte[]bytesStored=新字节[sck.ReceiveBufferSize];
int k1=sck.Receive(按存储);
对于(int i=0;i
我在几个网站上进行了测试,效果非常好。如果它不起作用,那么您应该通过添加更多的标题(最有可能的解决方案)来修复它。您是否有理由需要使用套接字,而不是,比如说,
System.Net.Http.HttpClient
?或Webclient(网络客户端)…没有具体原因。实际上,我不知道HttpCLient或Webclient。但无论如何,我想了解我上面的代码是什么。在发送主url后是否需要发送额外的“\r\n”?如果您不使用浏览器发送,请尝试在代码中删除它,以便复制与浏览器完全相同的行为。此外,正如jgauffin所说,您必须包括内容长度、主机等。如果您不想这样做,使用高级对象发送,如HttpWebRequest。我仍然收到SNP/3.0/107/BadPacket
听起来您的请求中还需要一些东西,比如连接、接受或可能接受编码。PVitt显示的是一个最小的请求,尽管这可能不足以满足您的特定协议。试着按照上面的建议使用WebClient,看看它是否有效,这样你就可以确定API是否能正常工作。根据公认的答案,它一定是内容长度
。谢谢。这正是我想要的。