我运行一个用 C 编写的 Linux 程序,它会通过解析 HTTP 响应定期接收数据,处理一些数字,然后通过另一个网页的 HTTP GET 报告结果。
我的问题是有时其中一个实例会“卡住”。
查看 top
我可以看到它处于 sk_wait_data
状态并且附加调试器显示它被 recv
调用阻止。
这是执行 TCP 连接的代码的最小版本(改编自 http://www.linuxhowtos.org/C_C++/socket.htm ):
int connectTCP(const char* host, const char* page, int portno) {
int sockfd;
struct sockaddr_in serv_addr;
struct hostent *server;
// Create socket //
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockfd < 0)
error("ERROR opening socket");
// Get ip from hostname //
server = gethostbyname(host);
if (server == NULL)
error("ERROR, can not find host\n");
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr, // Destination
(char *)server->h_addr, // Source
server->h_length); // Size
serv_addr.sin_port = htons(portno);
// Conect to socket //
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
return sockfd;
}
char* httpGet(const char* host, const char* page, int portno) {
int sockfd, n;
sockfd = connectTCP(host, page, portno);
memset(buffer, 0, sizeof(buffer));
sprintf(buffer, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n", page, host);
n = send(sockfd,buffer,strlen(buffer), 0);
if (n < 0)
error("ERROR writing to socket");
int count = 0;
do {
n = recv(sockfd, buffer + count, BUFFER_MAX_SIZE - count, 0);
if (n < 0) {
error("ERROR reading from socket");
}
count += n;
} while(n != 0);
close(sockfd);
return buffer;
}
最佳答案
代码中的错误:
如果
recv()
返回零,您应该关闭套接字并停止读取。如果
recv()
返回 -1,您应该报告错误、关闭套接字并停止读取,除非您设置了读取超时和errno
是 EAGAIN/EWOULDBLOCK,在这种情况下,您应该处理适合您的应用程序的超时。
关于linux - 了解 recv 永远阻塞的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371888/