C 选择不扫描2个以上描述符的系统调用
我正在编写一个服务于多个clientmax 5的服务器程序。当任何客户端连接到服务器时,服务器将描述符存储到一个数组中,并通过Select系统调用检查这些描述符中的任何活动。但是,它只从任意两个客户端读取数据,并且根本不提供rest客户端请求。下面是服务器的代码C 选择不扫描2个以上描述符的系统调用,c,linux,sockets,C,Linux,Sockets,我正在编写一个服务于多个clientmax 5的服务器程序。当任何客户端连接到服务器时,服务器将描述符存储到一个数组中,并通过Select系统调用检查这些描述符中的任何活动。但是,它只从任意两个客户端读取数据,并且根本不提供rest客户端请求。下面是服务器的代码 #define NUM_CLIENT 5 void main(int argc,char** argv) { int master_sock, newSocket, err; struct sockaddr_in Server_a
#define NUM_CLIENT 5
void main(int argc,char** argv)
{
int master_sock, newSocket, err;
struct sockaddr_in Server_addr, Client_addr;
char buf[100];
int i=0;
int activity;
//socket descriptors for select
fd_set readfd;
int client_fd[NUM_CLIENT]={-1,-1,-1,-1,-1};
//Socket creation
master_sock= socket(AF_INET,SOCK_STREAM,0);
if(master_sock<0){
perror("socket");
return;
}
//structure filling for listening to the port
Server_addr.sin_family = AF_INET;
Server_addr.sin_port = htons(atoi(argv[1]));
Server_addr.sin_addr.s_addr = INADDR_ANY;
//Binding to the Address and port filled in structure
err = bind(master_sock,(struct sockaddr*)&Server_addr,sizeof(Server_addr));
if(err<0){
perror("socket");
return;
}
printf("\nlistening to port");
err = listen(master_sock,NUM_CLIENT); //to inform, the willlingness to accept connections.
if(err<0){
perror("Listen");
return;
}
printf("\nAccepting connection");
while(1)
{
//Select modifies the objects in structure for any activity,
// So we need to load them again.
FD_ZERO(&readfd); //clearing the readfd list
FD_SET(master_sock,&readfd); //adding the descriptor for select to listen
for(i=0;i<NUM_CLIENT;i++){
if(client_fd[i] != -1){
FD_SET(client_fd[i],&readfd); //Add socket to the list
}
}
//Descriptors loaded..
//start Select operation....
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
if(activity < 0){
perror("Select");break;
}
printf("\nactivity happened in socket...");
//If activity related to master socket i.e. New client is trying to connect.
if( FD_ISSET(master_sock,&readfd) ) {
printf("\nactivity in master socket...");
int len = sizeof(Client_addr);
//Accept the connection
newSocket = accept(master_sock, (struct sockaddr*)&Client_addr ,&len); //blocking call
if(newSocket<0){
perror("accept");return;
}
printf("\nNew connection accepted");
// puts("Receiving data");
if( recv(newSocket,buf,100,0) > 0 ) //blocking call
printf("\n%s",buf);
else
strcpy(buf,"hey");
// puts("Sending data");
if( send(newSocket,buf,strlen(buf),0) < 0 )
perror("send");
//creating client database of descriptors
for(i=0;i<NUM_CLIENT;i++){
printf("\nfd[%d] = %d\n",i,client_fd[i]);
if(client_fd[i] == -1){
client_fd[i]= newSocket;
//FD_SET(newSocket,&readfd); //Add socket to the list
//printf("\nfd[%d] = %d\n",i,client_fd[i]);
break;
}
}
}
//If activity(read or write) in other sockets, check it out
printf("\nChecking Activity in Other File Descriptors\n");
for(i=0;i<NUM_CLIENT;i++){
if(FD_ISSET(client_fd[i],&readfd)){
printf("\nactivity in client %d ...",i);
// puts("Receiving data");
if( recv(client_fd[i],buf,100,0) > 0 ) //blocking call
puts(buf);
else
strcpy(buf,"hello");
// puts("Sending data");
if( send(client_fd[i],buf,strlen(buf)+1,0) == -1 )
perror("send");
//printf("\n%s",buf);
}
}
}
}
每个客户机在通过命令行提供的给定时间睡眠后发送和接收数据。示例:客户端1 5秒、客户端2 4秒等等
客户端的代码为:
void main(int argc, char** argv)
{
int fd, err;
char buf[100],buf2[100];
struct sockaddr_in server;
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd<0){
perror("socket");return;
}
I2A(buf,getpid()); //Integer to array conversion, returns array
strcat(buf,"Hello");
printf("%s\n",buf);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1])); //Host to network
server.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("Connecting with server\n");
if( connect(fd, (struct sockaddr*)&server,sizeof(server) ) < 0) {
perror("connect");return;
}
printf("Connected with server\n");
while(1){
// printf("Sending data\n");
if( send(fd,buf,20,0) < 0)
perror("send");
// printf("Receiving data\n");
if( recv(fd,buf2,sizeof(buf2),0) >0 )
printf("%s\n",buf2);
sleep(atoi(argv[2]));
}
提前谢谢。这行是错的:
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
要选择的第一个参数不应是NUM_CLIENT+1,而应是您调用FD_SET on的所有文件描述符值的最大文件描述符值加上一个。此行错误:
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
要选择的第一个参数不应是NUM_CLIENT+1,而应是您调用FD_SET on的所有文件描述符值的最大文件描述符值,再加上一个。NUM_CLIENT的名称不正确。要听的第二个参数是backlog队列的长度,而不是客户端的数量,它与select的第一个参数无关。请指定backlog队列的重要性好吗?为什么不能像这里这样使用NUM_客户机?文档中已经指定了“backlog队列的重要性”,我已经解释了称它为NUM_客户机的错误。我不知道你为什么要我重复一遍。NUM_客户的名字不好。要听的第二个参数是backlog队列的长度,而不是客户端的数量,它与select的第一个参数无关。请指定backlog队列的重要性好吗?为什么不能像这里这样使用NUM_客户机?文档中已经指定了“backlog队列的重要性”,我已经解释了称它为NUM_客户机的错误。我不知道你为什么要我重复一遍。