使用套接字C#的POST请求

时间:2011-02-18 12:48:02

标签: 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;

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

socket.Blocking = true;

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

*我正在使用一个ConnectSocket类,它在msdn作为示例提供(该链接指向俄语MSDN,对不起,我没有找到相同的英文文章,但你会明白的无论如何代码)

2 个答案:

答案 0 :(得分:3)

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

Encoding.UTF8.GetByteCount(request1+request3)+23).ToString()

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

请改为尝试:

"Content-Length: " + Encoding.UTF8.GetByteCount(request3).ToString() + "\r\n"

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

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

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

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

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

答案 1 :(得分:3)

正如人们已经指出的那样:HttpWebRequest不是导致性能问题的原因。切换到套接字实现不会影响任何事情。

事实是HttpWebRequest如果愿意的话可以做出数以万计的愚蠢事情,并且它仍然比从网络服务器获取内容的时间更快。

如果您对套接字和http协议有很好的了解,切换到套接字实现可能会加快速度。你显然没有,所以我建议你再次回到HttpWebRequest

如果您要从同一个网络服务器获取大量网页,则可能需要使用WebClient,因为它会使连接保持活动状态。

更新

  

我不需要很多连接,我需要一次发出1个请求,它应该尽可能快

好。那么你使用哪种实现并不重要。网络延迟总是比实际的HTTP客户端实现大很多。构建HTTP请求不会占用太多资源,解析响应也不会。