Hello, big bro.. Есть проблема.. Делаю сервер с 3 портами, работающими каждый независимо друг от друга... Использую неблокируюшие сокеты + select. Возникает следующая проблема - после добавления слушающих сокетов в множество селект прекрасно разбирает входящие соединения и разруливает их, нок примеру если мне необходимо принимать данные от нескольких клиентов (одновременно), после вызова accept только первый клиент посылает данные (на примере эхо-сервера и телнета проверил), а остальные хоть и подключаются, но при вводе строк не получают ответа.. Как только первый клиент отрубается, начинают работать остальные... Как поправить, где пропустил чего? -- функция принимает 3 порта, функция makeServerSocket принимает порт и возвращает дискриптор слушающего сокета (в ней выполняются последовательно socket, bind, listen). В этой функции также включен nonblocking mode через fcntl. Спс :) P.S. всякие kqueue, epoll и пр. не предлагать плиз взамен этому. Ибо геморрно и разбираться надо :( fork тоже не катит, как и треды... int startServer(int emulator_port, int controller_port, int system_port) { struct timeval timeout; fd_set master_set; fd_set working_set; char buffer[MAXLINE+1]; int end_server=0; int close_conn; int rc,desc_ready; int max_sd,new_sd; int i,len; int emu_sock, contr_sock, sys_sock; FD_ZERO(&master_set); emu_sock=makeServerSocket(emulator_port); FD_SET(emu_sock,&master_set); contr_sock=makeServerSocket(controller_port); FD_SET(contr_sock,&master_set); sys_sock=makeServerSocket(system_port); FD_SET(sys_sock,&master_set); max_sd=emu_sock+contr_sock+sys_sock; do { memcpy(&working_set,&master_set,sizeof(master_set)); printf("Waiting on select()...\n"); rc=select(max_sd+1,&working_set,NULL,NULL,NULL); if(rc<0) { perror("select() failed"); break; } if(rc==0) { printf("select() timed out. End program.\n"); break; } desc_ready=rc; for(i=0;i<=max_sd && desc_ready>0;++i) { if(FD_ISSET(i,&working_set)) { desc_ready-=1; if(i==emu_sock || i==contr_sock || i==sys_sock) { do { if(i==emu_sock) { new_sd=accept(i,NULL,NULL); if(fcntl(i,F_SETFL,O_NONBLOCK)<0) { perror("fcntl failed"); return -1; } printf("Emulator socket is readable\n"); } else if(i==contr_sock) { new_sd=accept(i,NULL,NULL); if(fcntl(i,F_SETFL,O_NONBLOCK)<0) { perror("fcntl failed"); return -1; } printf("Controller socket is readable\n"); } else { new_sd=accept(i,NULL,NULL); if(fcntl(i,F_SETFL,O_NONBLOCK)<0) { perror("fcntl failed"); return -1; } printf("System socket is readable\n"); } if(new_sd<0) { if(errno!=EWOULDBLOCK) { perror("accept() failed"); end_server=1; } break; } printf("New incoming connection - %d\n",new_sd); FD_SET(new_sd,&master_set); if(new_sd>max_sd) max_sd=new_sd; } while (new_sd!=-1); } else { printf("Descriptor %d is readable\n",i); close_conn=0; do { rc=recv(i,buffer,sizeof(buffer),0); if(rc<0) { if(errno!=EWOULDBLOCK) { perror("recv() failed"); close_conn=1; } break; } if(rc==0) { printf("Connection closed\n"); close_conn=1; break; } len=rc; printf("%d bytes received\n",len); rc=send(i,buffer,len,0); if(rc<0) { perror("send() failed"); close_conn=1; break; } } while (1); if(close_conn) { close(i); FD_CLR(i,&master_set); if(i==max_sd) { while(FD_ISSET(max_sd,&master_set) == 0) max_sd-=1; } } } } } } while(!end_server); for(i=0;i<=max_sd;++i) { if(FD_ISSET(i,&master_set)) close(i); } return 0; }
|