在Linux系统下,recv
函数用于从TCP连接的另一端接收数据。默认情况下,recv
是阻塞的,这意味着如果没有数据可读,调用recv
的线程会被挂起,直到有数据到达为止。
阻塞与非阻塞模式:
recv
时,如果缓冲区中没有数据,函数会一直等待,直到有数据到达。recv
时,如果缓冲区中没有数据,函数会立即返回一个错误码,而不是等待。在Linux下,可以通过以下几种方式设置套接字的阻塞模式:
socket
函数时,可以通过SOCK_STREAM
来创建一个TCP套接字,默认情况下是阻塞的。优势:
应用场景:
问题:如果服务器需要同时处理多个客户端连接,使用阻塞模式的recv
会导致服务器线程被单一的慢速客户端阻塞,影响整体性能。
解决方法:
O_NONBLOCK
标志,使recv
变为非阻塞模式。O_NONBLOCK
标志,使recv
变为非阻塞模式。select
、poll
、epoll
等机制来监听多个套接字的状态,只有当套接字可读时才调用recv
。aio
系列函数,可以在IO操作进行时执行其他任务。以下是一个简单的阻塞模式recv
使用示例:
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
int main() {
int sockfd;
struct sockaddr_in servaddr;
// 创建套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// 配置服务器地址
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8080);
servaddr.sin_addr.s_addr = INADDR_ANY;
// 连接到服务器
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
perror("connection with the server failed");
exit(EXIT_FAILURE);
}
char buffer[1024];
int n = recv(sockfd, buffer, sizeof(buffer), 0);
if (n < 0) {
perror("recv failed");
} else {
buffer[n] = '\0';
printf("Received message: %s\n", buffer);
}
close(sockfd);
return 0;
}
在这个例子中,如果没有数据可读,recv
会一直等待直到接收到数据为止。
没有搜到相关的文章