这应该如何完成?
我想接收一个(相当长的)HTTP 请求,但无法让它工作。
问题:如果没有标志,recv
不会读取整个消息。我想这是正常行为。据我了解,使用 MSG_WAITALL
标志会导致它阻塞,直到收到所有内容。但是,在这种情况下,调用将永远阻塞(直到我 ctrl+c 客户端(curl)进程为止。
下面有一个(仍然很长,但相当少)示例片段。 抱歉,它混合了 C 和 C++ 风格,但我想避免自己的错误,并主要坚持示例代码,并尽可能少地进行修改。
// Example largely based on: beej.us/guide/bgnet/output/html/singlepage/bgnet.html
// Mixes c-style and c++ due to my modifications.
// Only intended to reproduce a problem.
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sstream>
#include <iostream>
#include <cstring>
#define PORT "7004" // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(void)
{
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(servinfo); // all done with this structure
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
printf("server: waiting for connections...\n");
while(1) { // main accept() loop
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);
const uint EASILY_ENOUGH = 1000000;
char* buffer = new char[EASILY_ENOUGH + 1];
auto bytesRead = recv(new_fd, buffer, EASILY_ENOUGH, MSG_WAITALL); // FREEZES UNTIL I KILL THE CLIENT
// auto bytesRead = recv(new_fd, buffer, EASILY_ENOUGH, 0); // DOES NOT READ FULL REQUEST
if (bytesRead == -1) {
perror("recv");
close(new_fd);
continue;
}
buffer[bytesRead] = 0;
printf("bytes read: %ld\n", bytesRead);
printf("request: %s\n", buffer);
delete[] buffer;
std::string content = "some content.";
std::ostringstream os;
os << "HTTP/1.1 200 OK\r\n" << "Content-Length: " << content.size() << "\r\n"
<< "Connection: close\r\n" << "Content-Type: " << "plain/text"
<< "; charset=" << "utf-8" << "\r\n"
<< "Access-Control-Allow-Origin: *" << "\r\n" << "\r\n" << content;
std::string response = os.str();
printf("Response has size: %ld\n", response.size());
auto bytesSent = send(new_fd, response.c_str(), response.size(), 0);
printf("Method send claims it has sent %ld bytes\n", bytesSent);
close(new_fd);
}
return 0;
}
我使用的curl请求:
curl 'http://<myhost>:7004/___THE START___jsondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwa___THE END'
使用 MSG_WAITALL
我的服务器产生输出:
server: waiting for connections...
server: got connection from <my ip>
并且挂起,一旦我按下 CTRL+C curl ,它就会继续:
bytes read: 6379
request: GET /___THE START___jsondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwasondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwa___THE END HTTP/1.1
Host: <myhost>:7004
User-Agent: curl/7.49.0
Accept: */*
Response has size: 144
Method send claims it has sent 144 bytes
如果没有 MSG_WAITALL
和相同的请求,服务器会生成输出:
server: waiting for connections...
server: got connection from <my ip>
bytes read: 1448
request: GET /___THE START___jsondsadasdasdzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwaghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewjfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiwehfoewhfiuewhfiewhfhfiuewhfiwehfiuewwehgurwadzughjdssftzghuijerdftzghujiesdhufdewojfoewfhoiw
Response has size: 144
Method send claims it has sent 144 bytes
并且curl没有收到HTTP响应。 但是,较短的请求可以正确接收响应:
curl 'http://myhost:7004/___THE START___THE END__'
> some content.
服务器正确接收到完整的请求:
server: got connection from <my ip>
bytes read: 128
request: GET /___THE START___THE END__ HTTP/1.1
Host: <myhost>:7004
User-Agent: curl/7.49.0
Accept: */*
Response has size: 144
Method send claims it has sent 144 bytes
我确实明白,并非所有 TCP 数据包都会立即到达,这是正常的。但是,我组装完整请求的正确方法是什么?我还尝试了非阻塞变体,但通常会遇到没有更多数据可供读取的情况。如果有必要,我可以为此生成示例代码,类似地。
PS:当请求长度和连接不良程度超过阈值时,问题就会出现。我无法通过对本地主机的查询在我自己的计算机上重现它,并且根据我的连接,问题开始出现的请求长度会有所不同。
最佳答案
HTTP 是一种协议(protocol),它有结构和规则。阅读 RFC 2616 ,特别是Section 4 "HTTP Message" .
您的recv代码根本没有执行任何遵循协议(protocol)的操作。您不能只是盲目地读取任意缓冲区的数据并期望它是正确的完整 HTTP 请求。您必须根据协议(protocol)规则阅读请求。具体来说,您需要:
读取以 CRLF 分隔的文本行。这将包含请求的方法、资源和 HTTP 版本。
然后读取以 CRLF 分隔的请求 header 的可变长度列表。该列表以 CRLF CRLF 序列终止。
然后分析请求方法和 header ,判断请求是否有实体主体。如果是这样, header 会告诉您它是如何通过连接进行编码的(请参阅 Section 4.4 "Message Length" ),以便您知道需要如何读取它以及何时需要停止读取。
然后处理已完成的请求,并发送您的响应。
然后关闭连接,除非:
请求 HTTP 1.0 和
Connection: keep-alive
的请求出现在请求 header 中。请求 HTTP 1.1+ 和
Connection: close
的请求未出现在请求 header 中。
关于c++ - 接收(recv)完整请求(例如curl HTTP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43807297/