使用套接字C#的POST请求

Cra*_*ker 5 c# sockets post

我正试图为一个网站制作一个拍卖狙击手.要进行出价,您需要将4个参数(当然还有Cookie)发送到/ auction/place_bid.我需要使用套接字,而不是HttpWebRequest.这是代码:

        string request1 = "POST /auction/place_bid HTTP/1.1\r\nHost: *host here*\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)\r\nAccept: /*\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nX-Requested-With: XMLHttpRequest\r\n" + cookies +"\r\n";
        string request3 = "token=" + token + "&aid=" + aid + "&bidReq=" + ptzReq + "&recaptcha_challenge_field=" + rcf + "&recaptcha_response_field=" + rrf+"\r\n\r\n";
        string request2 = "Content-Length: " + (Encoding.UTF8.GetByteCount(request1+request3)+23).ToString() + "\r\n";
        byte[] dataSent = Encoding.UTF8.GetBytes(request1+request2+request3);
        byte[] dataReceived = new byte[10000];
        Socket socket = ConnectSocket(server, 80);
        if (socket == null)
        {
            return null;
        }
        socket.Send(dataSent, dataSent.Length, 0);
        int bytes = 0;
        string page = "";
        do
        {
            bytes = socket.Receive(dataReceived, dataReceived.Length, 0);
            page = page + Encoding.ASCII.GetString(dataReceived, 0, bytes);
        }
        while (bytes > 0);

        return page;
Run Code Online (Sandbox Code Playgroud)

当我试图接收网页时,Visual Studio说"无法立即完成对未阻塞套接字的操作",当我添加时

socket.Blocking = true;
Run Code Online (Sandbox Code Playgroud)

我的应用程序停止响应,约1分钟后它返回页面,但它是空的!当我试图提出GET请求时,它完美无缺.我希望你能帮助我.顺便说一句,这是我第一次使用套接字,所以我的代码非常糟糕,抱歉.

*我正在使用一个ConnectSocket类,这是在msdn上给出的一个例子(该链接指向俄语MSDN,对不起,我没有找到相同的英文文章,但你还是会理解代码)

eat*_*ter 4

标题Content-Length应指示内容的大小。您将其设置为标题内容的总大小。

Encoding.UTF8.GetByteCount(request1+request3)+23).ToString()
Run Code Online (Sandbox Code Playgroud)

由于消息的内容部分只是request3,因此服务器正在耐心等待ByteCount(request1)+23您从未发送的更多内容字节。

试试这个:

"Content-Length: " + Encoding.UTF8.GetByteCount(request3).ToString() + "\r\n"
Run Code Online (Sandbox Code Playgroud)

另一个问题看起来像你的循环:

do
{
    bytes = socket.Receive(dataReceived, dataReceived.Length, 0);
    page = page + Encoding.ASCII.GetString(dataReceived, 0, bytes);
}
while (bytes > 0);
Run Code Online (Sandbox Code Playgroud)

由于非阻塞套接字操作总是立即返回,无论它们是否已完成,因此您需要一个循环来不断调用,Receive()直到操作实际完成。Receive()在这里,如果对返回的调用0(几乎肯定是第一次),您将退出循环。

您至少应该将其更改为while (bytes <= 0)至少可以获得一些数据(可能只是第一个数据包的价值左右)。理想情况下,您应该继续调用Receive()直到看到Content-Length回复中的标头,然后继续调用Receive()直到标头末尾,然后读取Content-Length更多字节。

由于您使用的是套接字,因此您确实必须重新实现 HTTP 协议。