我正在编写服务于多个客户端的服务器程序(最多5个)。当任何客户端连接到服务器时,服务器将描述符存储到数组中,并通过选择系统调用检查这些描述符中的任何活动。但是,它只能从任何2个客户端读取,并且根本不会提供其他客户端请求。这是Server
的代码#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);
}
}
}
}
每个客户端在休眠一段时间后发送和接收数据(通过命令行提供)。示例:client1 5sec,client2 4sec等等......
客户的代码是:
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]));
}
提前致谢。
答案 0 :(得分:2)
这一行错了:
activity = select(NUM_CLIENT+1,&readfd,NULL,NULL,NULL); //wait here until any activiy occurs
select()的第一个参数不应该是NUM_CLIENT + 1,而是最大文件描述符值(在你调用FD_SET()的所有文件描述符值上),加上一个。