我使用select()编写了服务器程序。在这个程序中,我可以连接多个客户端。但是这台服务器只与最新的客户端交谈。我找不到问题。请帮帮我。对于客户端程序,我使用的是telnet命令(telnet 192.168.100.143 8181)。
SERVER.C
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define SERVER_IP "192.168.100.143"
#define CLIENT_IP "192.168.100.5"
#define PORT 8181
#define BUF_LEN 256
fd_set read_fd;
int32_t server_id, client_id, fdmax, ret, client_no;
struct sockaddr_in server, client;
int main()
{
int32_t opt=1;
socklen_t len;
char IP[INET_ADDRSTRLEN],buffer[BUF_LEN];
if((server_id=socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("Unable to create Server ocket");
exit(-1);
}
if( setsockopt(server_id, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) {
perror("setsockopt error...");
exit(-1);
}
memset((char *) &server,0, sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
inet_pton(AF_INET, SERVER_IP , &server.sin_addr);
bzero(&server.sin_zero,8);
if((bind(server_id,(struct sockaddr*)&server,sizeof(struct sockaddr_in)))==-1) {
perror("Unable to bind the server address...");
exit(-1);
}
listen(server_id,5);
printf("\nWaiting for connection\n");
FD_ZERO(&read_fd);
FD_SET(server_id,&read_fd);
fdmax=server_id;
while(1){
printf("%d\n",__LINE__);
printf("fdmax = %d \n",fdmax);
if((select(fdmax+1,&read_fd,NULL,NULL,NULL)) <0) {
perror("Select\n");
return -1;
}
printf("%d\n",__LINE__);
if(FD_ISSET(server_id,&read_fd)) {
if((client_id=accept(server_id,(struct sockaddr*)&client,&len))==-1) {
perror("Cannot accept the client...");
exit(-1);
}
printf("New client %d connectd \n",client_id);
FD_SET(client_id, &read_fd);
fdmax = client_id;
} else {
for(client_no = server_id+1; client_no <=fdmax; client_no++) {
if(FD_ISSET(client_no, &read_fd)) {
printf("%d\n",__LINE__);
ret = recv(client_no, buffer, BUF_LEN, 0);
if(ret == 0) {
printf("client %d disconnectd \n",client_no);
FD_CLR(client_no, &read_fd);
close(client_no);
break;
} else {
printf("Received from client %d = %s \n",client_no,buffer);
}
}
}
}
}
close(client_id);
close(server_id);
return 0;
}
答案 0 :(得分:1)
您需要在while(1)
的每次迭代中对所有文件描述符(包括侦听器fd)调用FD_SET。
在您的代码中,server_id
循环内未设置while(1)
。因此,一旦第一个客户端连接并以数据形式发送,就不会通知新的套接字连接及其上的数据。&#39;
while(1)
{
FD_SET(server_id,&read_fd); //This should work.
...
}