这是我的服务器程序.
/* server.c */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
int main()
{
int sockfd;
int ret;
int yes = 1;
struct addrinfo hints,*ai;
memset(&hints,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((ret = getaddrinfo(NULL,"8000",&hints,&ai)) == -1) {
fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(ret));
return 1;
}
sockfd = socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol);
if (sockfd == -1) {
perror("server: socket");
return 1;
}
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes) == -1) {
perror("server: setsockopt");
close(sockfd);
return 1;
}
if (bind(sockfd,ai->ai_addr,ai->ai_addrlen) == -1) {
perror("server: bind");
close(sockfd);
return 1;
}
freeaddrinfo(ai);
if (listen(sockfd,2) == -1) {
perror("server: listen");
close(sockfd);
return 1;
}
printf("server: listening ...\n");
printf("server: sleep() to allow multiple clients to connect ...\n");
sleep(10);
printf("server: accepting ...\n");
while (1) {
int connfd;
struct sockaddr_storage client_addr;
socklen_t client_addrlen = sizeof client_addr;
char buffer[1024];
int bytes;
connfd = accept(sockfd,(struct sockaddr *) &client_addr,&client_addrlen);
if (connfd == -1) {
perror("server: accept");
continue;
}
if ((bytes = recv(connfd,buffer,sizeof buffer,0)) == -1) {
perror("server: recv");
continue;
}
printf("server: recv: %.*s\n",(int) bytes,buffer);
close(connfd);
}
return 0;
}
这是我的客户端程序.
/* client.c */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc,char **argv)
{
int sockfd;
int ret;
struct addrinfo hints,*ai;
if (argc != 2) {
fprintf(stderr,"usage: %s MSG\n",argv[0]);
return 1;
}
memset(&hints,sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if ((ret = getaddrinfo(NULL,"client: getaddrinfo: %s\n",ai->ai_protocol);
if (sockfd == -1) {
perror("client: socket");
return 1;
}
if (connect(sockfd,ai->ai_addrlen) == -1) {
perror("client: connect");
close(sockfd);
return -1;
}
printf("client: connected\n");
if (send(sockfd,argv[1],strlen(argv[1]),0) == -1) {
perror("client: send");
close(sockfd);
return -1;
}
printf("client: send: %s\n",argv[1]);
freeaddrinfo(ai);
close(sockfd);
return 0;
}
我用以下脚本编译并运行这些程序.
# run.sh gcc -std=c99 -Wall -Wextra -Wpedantic -D_DEFAULT_SOURCE server.c -o server gcc -std=c99 -Wall -Wextra -Wpedantic -D_DEFAULT_SOURCE client.c -o client ./server & sleep 1 ./client hello1 & sleep 1 ./client hello2 & sleep 1 ./client hello3 & sleep 1 ./client hello4 & sleep 1 ./client hello5 & sleep 5 pkill server
当我运行上面的脚本,我得到这个输出.
$sh run.sh server: listening ... server: sleep() to allow multiple clients to connect ... client: connected client: send: hello1 client: connected client: send: hello2 client: connected client: send: hello3 client: connected client: send: hello4 client: connected client: send: hello5 server: accepting ... server: recv: hello1 server: recv: hello2 server: recv: hello3
输出显示当服务器在listen()和accept()之间休眠时,所有五个客户端都可以成功地将()和send()连接到服务器.但是,服务器只能接受()和recv()三个客户端.
我不明白以下内容.
>服务器程序调用listen()与backlog参数为2.为什么所有五个客户端成功连接() – 然后?我期望只有2个connect()成功.
>为什么服务器能够从3个客户端而不是2接受()和recv()?
解决方法
The server program invokes listen() with the backlog parameter as 2.
Why did all five clients succeed in connect()-ing then?
backlog参数只是listen()的一个提示.从POSIX doc:
The backlog argument provides a hint to the implementation which the implementation shall use to limit the number of outstanding connections in the socket’s listen queue. Implementations may impose a limit on backlog and silently reduce the specified value. normally,a larger backlog argument value shall result in a larger or equal length of the listen queue. Implementations shall support values of backlog up to SOMAXCONN,defined in .