У меня есть приложение для клиентского/серверного приложения Linux. Я придумал странный сценарий, но я не знаю, есть ли какие-либо последствия с этим приложением. У меня есть серверная сторона, которая может принимать N соединений, например, этот сервер будет принимать 100 соединений. В этом сценарии я создаю сокет прослушивания в основном потоке, затем создаю 100 потоков, и каждый поток имеет независимые accept() и select() iomux, также каждый поток может принимать только одно соединение.Может ли дескриптор приложения N принимать соединения, и каждый из них принимает независимый поток
Мое беспокойство здесь, если два одновременных accept() хотят принять один и тот же сокет (соединение) из-за выбора, готов к чтению в одном и том же сокете, я не знаю, является ли одновременное принятие потоком безопасным в ядро, и только один прием может обрабатывать это входящее соединение, а другой будет ждать другого соединения?
Я пробовал это на моей машине RedHat, которая отлично работает, но я не знаю. Если мне повезет, чтобы избежать тупика!
Благодаря
rc = bind(sd, (struct sockaddr_in *)& groupSock, sizeof(struct sockaddr_in));
CHECK_VALUE("Bind address error", rc, 0, goto cleanup);
rc = listen(sd, 10);
CHECK_VALUE("listen", rc, 0, goto cleanup);
for(; count< num_socks; count++){
par_data[count].sd = sd;
par_data[count].thread_num = count;
par_data[count].err_chk = -1;
rc = pthread_create(&thread_id[count], NULL, accept_sock_thread, (void *)& par_data[count]);
CHECK_VALUE("pthread_create", rc, 0, goto cleanup);
}
void * accept_sock_thread(void* atr){
int rc;
int sock = INVALID_SOCKET;
int datalen = config.traffic;
char *databuf = NULL;
struct thread_data *data = NULL;
struct sockaddr_in tcp_remote;
struct timeval t;
socklen_t size;
fd_set socks;
databuf = malloc(sizeof(char) * datalen);
memset(databuf, 0, datalen);
data = (struct thread_data*) atr;
DEBUG(my_debug_flags, ENTER_FUNCT, ("Enter Function accept_sock_thread thread_num %d \n", data->thread_num));
FD_ZERO(&socks);
FD_SET(data->sd, &socks);
t.tv_sec = 25;
t.tv_usec = 0;
rc = select(data->sd + 1 , &socks, NULL, NULL,&t);
if(rc < 0){
VL_MISC_ERR(("Error in select with Errno: %d", errno));
goto cleanup;
}
else if(rc == 0){
VL_MISC_ERR(("Accept Select returned a TIEMOUT."));
goto cleanup;
}
size = sizeof(struct sockaddr_in);
sock = accept(data->sd, (struct sockaddr *)& tcp_remote, &size);
CHECK_NOT_EQUAL("tcp accept error", sock, INVALID_SOCKET, goto cleanup);
cleanup:
// sleep(2); /* avoid EOF */
if(sock != INVALID_SOCKET){
rc = close(sock);
if(rc != 0){
data->err_chk = -1;
}
}
return NULL;
}
Можете ли вы опубликовать код обработки соединения? Сценарий, который вы описываете, может быть хорошим, но он также зависит от реализации. –
sd = socket (AF_INET, SOCK_STREAM, 0); rc = bind (sd, (struct sockaddr_in *) & groupSock, sizeof (struct sockaddr_in)); rc = listen (sd, 100); для (; count
На самом деле это произошло, см. Мой ответ. –