Я строю клиент-серверную программу на C, используя сокеты. И мой клиент, и мой сервер используют фиксированное количество потоков для работы. Сначала я протестировал очень мало клиентских и серверных потоков (5 и 3), и все, казалось, работало нормально. Но теперь я попытался увеличить число клиентских потоков до 500 (в то время как количество серверных потоков остается на 3), но все ломается. Клиент первой сотни или около того может отправить свой запрос и получить ответ, но остальные ничего не получают с сервера.
Я работаю над подсистемой Windows Debian, если это что-то изменит.
Я также попытался увеличить число потоков сервера до 300, но проблема все еще возникает.
Вот мой (очень) упрощенный код.
Клиентская нить
int client_socket= socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(2018);
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
memset(&addr.sin_zero, 0, sizeof(addr.sin_zero));
connect(client_socket, (struct sockaddr *) &addr, sizeof(addr));
int response;
int cid = 1;
send(client_socket, &cid, sizeof(int), 0);
int len = read_socket(socket, &response, sizeof(int), 1000);
if (len == 0) {
printf("No response");
} else {
printf("Response");
}
close(client_socket);
Серверная нить
int socket_fd, cid, len;
while (1)
{
socket_fd =
accept(socket_fd, (struct sockaddr *)&thread_addr, &socket_len);
if (socket_fd> 0) {
int cid;
int len = read_socket(socket_fd, &cid, sizeof(cid), 1000);
if (len == 0) {
printf("Nothing");
}
send(socket_fd, &cid, sizeof(int),0);
close(socket_fd);
}
}
А вот и моя вспомогательная функция read_socket()
ssize_t read_socket(int sockfd, void *buf, size_t obj_sz, int timeout) {
int ret;
int len = 0;
struct pollfd fds[1];
fds->fd = sockfd;
fds->events = POLLIN;
fds->revents = 0;
do {
// wait for data or timeout
ret = poll(fds, 1, timeout);
if (ret > 0) {
if (fds->revents & POLLIN) {
ret = recv(sockfd, (char*)buf + len, obj_sz - len, 0);
if (ret < 0) {
// abort connection
perror("recv()");
return -1;
}
len += ret;
}
} else {
// TCP error or timeout
if (ret < 0) {
perror("poll()");
}
break;
}
} while (ret != 0 && len < obj_sz);
return ret;
}
Как я уже сказал, некоторые клиенты могут без проблем завершить выполнение, но многие из них не получают ответа от сервера.