Я работаю над программой клиент-сервер, которая использует вызовы select () для прослушивания нескольких сокетов. Но мой вызов select блокируется, хотя у меня есть сообщение в одном из этих сокетов, вызов select () не распознает его и все еще ждет там неопределенно долго.
В программе 2 объекта: мастер и клиент.
Мастер знает количество клиентов, с которыми он будет работать, и ожидает подключения клиентов к нему. Как только он получает подтверждение клиента, он сохраняет свою информацию. Как только все клиенты подключены, он отправляет информацию о соседнем клиенте каждому клиенту, чтобы он мог сформировать сеть. Именно здесь я использую select () для мониторинга многих сокетов,
мастер имеет розетку, к которой подключен каждый ребенок тат
у клиента есть 3 основных розетки
с1-поговорить с мастером
s2-child прослушивает соединение на этом сокете
соседний - сокет, на котором его сосед ожидает подключения. (т.е. S2 в соседнем)
p- сокет, который является результатом соединения от его соседа (accept s2 - возвращает ths)
Я использую select для прослушивания сервера, его собственный сокет для входящих соединений и один раз.
Первоначально мой сервер отправляет строку "привет" одному из клиентов, который получает это сообщение и передает его соседу, таким образом, когда строка возвращается обратно к первому дочернему элементу, который получил это сообщение от сервера, он передает это своему соседу. Но все, хотя все дочерние элементы находятся в select (), ожидая ввода. Что может вызвать это ??
void main(int argc, char **argv) {
int s1, s2, n, server_port, sc1, sc2, rv, rc, left_peer_port;
int peer_port;
fd_set writefds, readfds;
struct timeval tv;
struct hostent *server_info, *child_info, *left_peer_info;
int start_flag = 0;
struct sockaddr_in server, peer, incoming;
char host_child[64];
char *left_host = malloc(1);
char *right_host = malloc(1);
char buf1[256];
char buf2[256];
server_port = atoi(argv[2]);
//speak to peer using this
s2 = socket(AF_INET, SOCK_STREAM, 0);
if (s2 < 0) {
perror("socket:");
exit(s2);
}
peer_port = server_port + 1;
gethostname(host_child, sizeof host_child);
child_info = gethostbyname(host_child);
if (child_info == NULL) {
fprintf(stderr, "%s: host not found (%s)\n", argv[0], host_child);
exit(1);
}
peer.sin_family = AF_INET;
memcpy(&peer.sin_addr, child_info->h_addr_list[0], child_info->h_length);
int changeport = 0;
do {
peer.sin_port = htons(peer_port);
rc = bind(s2, (struct sockaddr *) &peer, sizeof(peer));
if (rc < 0) {
//perror("bind:");
peer_port++;
changeport = 1;
//exit(rc);
} else {
changeport = 0;
}
} while (changeport == 1);
if (listen(s2, 100) == -1) {
perror("listen");
exit(3);
}
//Now talk to server
server_info = gethostbyname(argv[1]);
if (server_info == NULL) {
fprintf(stderr, "%s: host not found\n", argv[0]);
exit(1);
}
// pretend we've connected both to a server at this point
//speak to server using this
s1 = socket(AF_INET, SOCK_STREAM, 0);
if (s1 < 0) {
perror("socket:");
exit(s1);
}
server.sin_family = AF_INET;
server.sin_port = htons(server_port);
memcpy(&server.sin_addr, server_info->h_addr_list[0], server_info->h_length);
//To talk to the server
sc1 = connect(s1, (struct sockaddr *) &server, sizeof(server));
if (sc1 < 0) {
perror("connect:");
exit(sc1);
}
int send_len;
char *str = malloc(1);
sprintf(str, "%d", peer_port);
printf("\nport-here=%s\n", str);
send_len = send(s1, str, strlen(str), 0);
if (send_len != strlen(str)) {
perror("send");
exit(1);
}
int recv_len;
char buf[100];
int ref = 0;
int recv_stage = 0;
int start_id;
recv_len = recv(s1, buf, 34, 0);
if (recv_len < 0) {
perror("recv");
exit(1);
}
buf[recv_len] = '\0';
char *temp_port;
if (!strcmp("close", buf))
printf("%s", buf);
//break;
else {
char *temp_buffer = malloc(1);
char *id = malloc(100);
char *pp = malloc(1);
strcpy(temp_buffer, buf);
char *search = ":";
temp_port = strtok(temp_buffer, search);
strcpy(buf, temp_port);
printf("temp_name%s", temp_port);
temp_port = strtok(NULL, search);
strcpy(pp, temp_port);
printf("temp_port%s", temp_port);
temp_port = strtok(NULL, search);
strcpy(id, temp_port);
printf("id%s", temp_port);
strcpy(temp_port, pp);
printf("\nbuf=%s\n", buf);
printf("\nport=%s\n", temp_port);
printf("\nid=%s\n", id);
start_id = atoi(id);
}
//To send packet to its neighbour
left_peer_info = gethostbyname(buf);
printf("\nleft host=%s\n", buf);
if (left_peer_info == NULL) {
fprintf(stderr, "%s: host not found\n", left_host);
exit(1);
}
left_peer_port = atoi(temp_port);
int neighbour_socket;
struct hostent *neighbour_info;
struct sockaddr_in neighbour;
neighbour_socket = socket(AF_INET, SOCK_STREAM, 0);
if (neighbour_socket < 0) {
perror("socket:");
exit(neighbour_socket);
}
neighbour_info = left_peer_info;
neighbour.sin_family = AF_INET;
neighbour.sin_port = htons(left_peer_port);
memcpy(&neighbour.sin_addr, neighbour_info->h_addr_list[0], neighbour_info->h_length);
printf("\nconnected to port %d\n", left_peer_port);
//To talk to the neighbour
printf("\ncomes here\n");
//Listen on this socket connection for potato
int send_peer_len;
int nfds;
nfds = MAX(MAX(neighbour_socket, s2), s1);
// clear the set ahead of time
FD_ZERO(&writefds);
// add our descriptors to the set
FD_SET(neighbour_socket, &writefds);
FD_SET(s1, &writefds);
FD_SET(s2, &writefds);
//FD_SET(s2, &writefds);
FD_ZERO(&readfds);
FD_SET(neighbour_socket, &readfds);
FD_SET(s1, &readfds);
FD_SET(s2, &readfds);
//select()
// since we got s2 second, it's the "greater", so we use that for
// the n param in select()
//n = s1 + 1;
// wait until either socket has data ready to be recv()d (timeout 10.5 secs)
tv.tv_sec = 10;
tv.tv_usec = 500000;
int fds[3];
fds[0] = s1;
fds[1] = s2;
fds[2] = neighbour_socket;
int p = 0;
int p_flag = 0;
while (1) {
printf("\n nfds = %d , p = %d \n", nfds, p);
char buf_msg[64];
//This is where the error occurs //
rv = select(nfds, &readfds, NULL, NULL, 0);
//This is where the error occurs //
if (rv == -1) {
perror("select"); // error occurred in select()
} else if (rv == 0) {
printf("Timeout occurred! No data after 10.5 seconds.\n");
} else {
// one or both of the descriptors have data
//reading message from server
int select_fd;
for (select_fd = 0; select_fd <= nfds; select_fd++) {
if (FD_ISSET(select_fd, &readfds) != 0) {
if (select_fd == s1) {
recv_len = 0;
recv_len = recv(s1, buf_msg, 34, 0);
if (recv_len < 0) {
perror("recv");
exit(1);
}
buf_msg[recv_len] = '\0';
printf("\nreceived from server = %s\n", buf_msg);
//send to neighbour
int sc3;
sc3 = connect(neighbour_socket, (struct sockaddr *) &neighbour, sizeof(neighbour));
if (sc3 < 0) {
perror("connect:");
exit(sc3);
}
str = malloc(1);
strcpy(str, buf_msg);
send_len = send(neighbour_socket, str, strlen(str), 0);
printf("\n send - len - s1 - %d\n", send_len);
if (send_len != strlen(str)) {
perror("send");
exit(1);
}
start_flag = 1;
//FD_CLR(s1, &readfds);
printf("\ncrossed server\n");
} else if (select_fd == s2) {
int list_len = sizeof incoming;
printf("\ninside client\n");
printf("\nWaiting for accept in S2\n");
if (p_flag == 0) {
p_flag = 1;
p = accept(s2, (struct sockaddr *) &incoming, &list_len);
printf("\nConnection accepted in S2\n");
if (p < 0) {
perror("bind:");
exit(rc);
}
}
nfds = MAX(nfds, p);
recv_len = 0;
buf_msg[recv_len] = '\0';
recv_len = recv(p, buf_msg, 34, 0);
if (recv_len < 0) {
perror("recv");
exit(1);
}
buf_msg[recv_len] = '\0';
printf("\nreceived from client = %s\n", buf_msg);
//send to neighbour
//if(start_id!=1){
int sc3;
sc3 = connect(neighbour_socket, (struct sockaddr *) &neighbour, sizeof(neighbour));
if (sc3 < 0) {
perror("connect:");
//exit(sc3);
}
//}
str = malloc(1);
strcpy(str, buf_msg);
send_len = send(neighbour_socket, str, strlen(str), 0);
printf("\n send - len - s2 - %d\n", send_len);
if (send_len != strlen(str)) {
perror("send");
exit(1);
}
} else if (select_fd == neighbour_socket) {
printf("\ncomes in\n");
} else if (select_fd == p && p != 0) {
int list_len = sizeof incoming;
printf("\ninside p\n");
recv_len = 0;
buf_msg[recv_len] = '\0';
printf("\nwaiting at recv in P\n");
recv_len = recv(p, buf_msg, 34, 0);
printf("\ncrossed at recv in P\n");
if (recv_len < 0) {
perror("recv");
exit(1);
}
buf_msg[recv_len] = '\0';
printf("\nreceived from client = %s\n", buf_msg);
//send to neighbour
str = malloc(1);
strcpy(str, buf_msg);
send_len = send(neighbour_socket, str, strlen(str), 0);
printf("\n send - len - neighbour - %d\n", send_len);
if (send_len != strlen(str)) {
perror("send");
exit(1);
}
}
}
}
FD_ZERO(&readfds);
//FD_SET(neighbour_socket,&readfds);
FD_SET(s1, &readfds);
FD_SET(neighbour_socket, &readfds);
if (p_flag == 1) {
printf("\nsetting P\n");
FD_SET(p, &readfds);
FD_SET(s2, &readfds);
p_flag = 0;
} else {
printf("\nNot setting P\n");
FD_SET(s2, &readfds);
}
}
}
close(s1);
close(s2);
}
Заранее спасибо.