int listen(int s, int backlog);
《TCP/IP详解 卷1:协议》的Page195有详细解释。
1)backlog 用于在TCP层接收链接的缓冲池的最大个数,这个个数可在应用层中的listen函数里设置,当客户链接请求大于这个个数(缓冲池满),其它的未进入链接缓冲池的客户端在tcp层上tcp模块会自动重新链接,直到超时(大约57秒后)
2)我们的应用层的链接完成是要从tcp层的链接缓冲池中移出一个(accept函数实现)
简单点说就是你指定backlog为2,假设链接缓冲池中已经有2个链接了,那么别的client链接会返回超时信息等,就是说会链接不上,就是connect函数会返回错误!
listen是连接未完成的缓冲队列,不是当前连接的个数。如果连接队列满的话,再有客户端请求也就是connect会不成功。
在AIX上,backlog = 10允许队列里有16个未处理的连接,更多的连接会出现Connection time out错误。
其他的系统里这个数目会有所不同。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define host
"127.0.0.1"
#define port
27104
int server(void)
{
int sockfd;
struct sockaddr_in addr;
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if
(sockfd < 0) {
perror("socket");
exit(1);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if
(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)))
{
perror("socket");
exit(1);
}
if
(listen(sockfd, 10)) {
perror("socket");
exit(1);
}
return 0;
}
int client(void)
{
int i;
int sockfd;
struct sockaddr_in addr;
for (i = 0; i < 100; i++) {
sockfd = socket(PF_INET,
SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket");
exit(1);
}
memset(&addr, 0,
sizeof(addr));
addr.sin_family =
AF_INET;
addr.sin_port =
htons(port);
addr.sin_addr.s_addr =
inet_addr(host);
printf("%s:%d d - %s\n",
host, port, i, "connecting ...");
if (connect(sockfd, (struct
sockaddr *)&addr, sizeof(addr))) {
perror("socket");
exit(1);
} else {
printf("%s:%d d - %s\n", host, port, i,
"connected");
}
}
sleep(1);
return 0;
}
int main(void)
{
pid_t pid;
if
((pid = fork()) == 0) {
sleep(1);
return client();
}
else if (pid > 0) {
server();
waitpid(pid, NULL,
0);
}
else {
perror("fork");
return 1;
}
return 0;
}
加载中,请稍候......