Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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++ recv()上的http客户端块_C++_Http_Recv - Fatal编程技术网

C++ recv()上的http客户端块

C++ recv()上的http客户端块,c++,http,recv,C++,Http,Recv,我需要一些关于编写http客户端的帮助。当我试图从Web服务器接收数据时,麻烦就来了。recv()调用将阻止该程序。任何更好的方向都会非常有用,我将在下面发布我的代码: if ( argc != 2 ) { cerr << "Usage: " << argv[0]; cerr << " <URI>" << endl; return 1; } else { uri_string = argv[1]; }

我需要一些关于编写http客户端的帮助。当我试图从Web服务器接收数据时,麻烦就来了。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;
if(argc!=2)
{
cerr打印(请求字符串);
//这是个问题吗

如果客户是comamnd line,则可以。
如果是GUI,那么检索数据的线程应该与UI线程不同

但解决方法是使用select()
这将告诉您是否有要从端口读取的内容。
这样就允许您在等待时做其他工作。

这是个问题吗

如果客户是comamnd line,则可以。
如果是GUI,那么检索数据的线程应该与UI线程不同

但解决方法是使用select()
这将告诉您是否有要从端口读取的内容。

因此,允许您在等待时执行其他工作。

recv()
应该阻止它,直到它得到响应。您确定正确写入请求,并且服务器正在响应它吗?可以将文件描述符置于非阻止模式,并使用
select()对其进行测试
poll()
,但我猜您只是在某个地方有一个协议错误。您期望的行为是什么?

recv()
假定在收到响应之前阻止它。您确定您正确写入了请求,并且服务器正在响应它吗?可以将文件描述符置于非阻止模式,并使用
select()
poll()对其进行测试
,但我猜您只是在某个地方有一个协议错误。您期望的行为是什么?

HTTP请求应该以空行结束,即


GET/HTTP/1.1
主持人:blah.com
打印(请求字符串+“\n”)


离题:您知道C中有现成的HTTP客户机,对吧?(比如libcurl)。

HTTP请求应该以空行结束,即


GET/HTTP/1.1
主持人:blah.com
打印(请求字符串+“\n”)


题外话:您知道C中有现成的HTTP客户端,对吗?(例如libcurl)。

您使用的是阻塞TCP/IP套接字,但您没有查看HTTP应答的“Content Length”头来了解要读取的字节数。您当前的读取逻辑是调用recv()在循环中,直到收到最大1024字节。如果服务器发送的字节数少于1024字节,您将被最终阻止,因为您调用recv()的次数太多,请求的字节数太多。

您使用的是阻止TCP/IP套接字,但您没有查看HTTP回复的“内容长度”标头以了解要读取的字节数。您当前的读取逻辑正在循环中调用recv(),直到收到最大1024字节。如果服务器发送的字节数少于1024字节,则您将被不确定地阻止,因为您正在调用recv()请求太多字节的次数太多。

您必须接收内容长度字段中的许多字节。 您必须更改行:
if(recv_len==-1)
致:


if(recv_len您必须接收内容长度字段中的许多字节。
您必须更改行:
if(recv_len==-1)
致:


if(recv_len我知道它应该阻止直到得到响应,但它应该得到响应,当我打印出我发送给Web服务器的消息时,它的格式如下:GET/HTTP/1.1接受编码:identity;q=1.0,*;q=0主机:google.com TE:identity;q=1.0,chunked;q=0,*;q=0有什么理由我不应该得到响应吗我想你需要问你的服务器,而不是我您是否查看了数据包转储以验证该命令是否到达服务器、生成响应并完整返回?我知道它应该阻止,直到得到响应,但它应该得到响应,当我打印出发送到Web服务器的消息时,它具有以下格式:GET/HTTP/1.1 Accept Encoding:identity;q=1.0,*;q=0主机:google.com TE:identity;q=1.0,chunked;q=0,*;q=0有什么理由我不应该得到回复吗?我想你需要问你的服务器,而不是我。:)您是否查看了数据包转储以验证命令是否到达服务器、生成响应并完整返回?感谢您的回复,我找到了需要执行的操作。如果响应没有任何“内容长度”标题,该怎么办?@NeDark:Read RFC 2616()第4.4节,它告诉你该做什么。谢谢你的回复,我知道我需要做什么。如果响应没有任何“内容长度”标题怎么办?@NeDark:Read RFC 2616()第4.4节,它告诉你该做什么。
GET / HTTP/1.1
Host: blah.com
                    <- this here is an empty line
if ( recv_len <= 0 ) break;
else if ( recv_len == -1 )