c++ - recv() 上的 http 客户端 block

标签 c++ http recv

我需要一些帮助来编写一个 http 客户端。当我尝试从网络服务器接收数据时,问题就来了。 recv() 调用会阻塞程序。任何更好的方向都会非常有帮助,我将在下面发布我的代码:

if ( argc != 2 )
{
    cerr << "Usage: " << argv[0];
    cerr << " <URI>" << endl;
    return 1;
}
else
{
    uri_string = argv[1];
}

// Create URI object and have it parse the uri_string
URI *uri = URI::Parse(uri_string);

if ( uri == NULL )
{
    cerr << "Error: Cannot parse URI." << endl;
    return 2;
}

// Check the port number specified, if none use port 80
unsigned port = 80;
if ( uri->Is_port_defined() )
{
    port = uri->Get_port();
}

// Create TCP socket and connect to server
int tcp_sock = socket( AF_INET, SOCK_STREAM, 0 );
if ( tcp_sock < 0 )
{
    cerr << "Unable to create TCP socket." << endl;
    return 3;
}

sockaddr_in server;
socklen_t slen = sizeof(server);

server.sin_family = AF_INET;
server.sin_port = htons( port );
hostent *hostp = gethostbyname( uri->Get_host().c_str() );
memcpy( &server.sin_addr, hostp->h_addr, hostp->h_length );

if ( connect( tcp_sock, (sockaddr*)&server, slen ) < 0 )
{
    cerr << "Unable to connect to server via TCP." << endl;
    close( tcp_sock );
    return 4;
}

// Build HTTP request to send to server
HTTP_Request *request = HTTP_Request::Create_GET_request( uri->Get_path() );
request->Set_host( uri->Get_host() );
string request_string = "";
request->Print( request_string );

//cout << request_string << endl;

// Send it to the server, wait for reply and use HTTP_Response to get reply
send( tcp_sock, &request_string, sizeof(request_string), 0 );

char recv_buffer[1024];
int bytes_recv = 0;
while ( bytes_recv < 1024 )
{
    int recv_len = recv( tcp_sock, recv_buffer + bytes_recv,
        1024 - bytes_recv, 0 );
    if ( recv_len == -1 )
    {
        cerr << "Error receiving response from server." << endl;
        close( tcp_sock );
        return 5;
    }
    bytes_recv += recv_len;
}


HTTP_Response *response = HTTP_Response::Parse(recv_buffer, bytes_recv);
string response_string = "";
response->Print( response_string );
cout << response_string << endl;

return 0;

最佳答案

您正在使用阻塞式 TCP/IP 套接字,但您没有查看 HTTP 回复的“Content-Length” header 来了解要读取多少字节。您当前的阅读逻辑是在循环中调用 recv(),直到收到最多 1024 个字节。如果服务器发送少于 1024 字节,您将被无限期地阻止,因为您调用 recv() 的次数太多,要求的字节数太多。

关于c++ - recv() 上的 http 客户端 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1580614/

相关文章:

c++ - 协助添加未知功能。 (C++)

c++ - 如何使用 std::ostringstream 截断整型的宽度?

ruby-on-rails - 如何在 Rails 应用程序的 mailgun 消息 api 中检索存储的消息

c - 来回发送和接收

c++ - 初始化 SDL_Mixer 给出错误 "No available audio device"

c++ - 虚拟文件夹在 Windows 7 的 CFileDialog 中不可见

java - http请求如何设置源IP?

php - 使用 PHP/JavaScript 从服务器向用户推送通知

c++ - C++ 中 TCP 套接字的 recv 函数

c - 线程不更新但阻塞在recv()上