Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.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

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
C#:如何使用套接字执行HTTP请求?_C#_Sockets - Fatal编程技术网

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是否能正常工作。根据公认的答案,它一定是
内容长度
。谢谢。这正是我想要的。