Witam.
Pisze sobie najprostszy serwer pod linuxem obsługujący kilku klientów naraz. Zastosowałem funkcję
select
Niestety pomimo wszystkiego nie działa mi, chociaż wygląda poprawnie.
Kod serwera:
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#define BACKLOG 5
#define MY_PORT 5000
#define IP "192.168.8.21"
int main() {
int sockfd, new_sockfd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
struct timeval tv;
fd_set read_fds;
fd_set write_fds;
fd_set master_fds;
int bytes;
char buffor[100];
int yes = 1;
socklen_t sin_size;
int fdmax;
int i;
int status;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))) == -1) {
perror("setsockopt");
exit(1);
}
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&master_fds);
//FD_ZERO(&status);
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MY_PORT);
my_addr.sin_addr.s_addr = inet_addr(IP);
memset(&(my_addr.sin_zero), '\0', 8);
if((bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))) == -1) {
perror("bind");
exit(1);
}
if((listen(sockfd, BACKLOG)) == -1) {
perror("listen");
exit(1);
}
FD_SET(sockfd, &read_fds);
fdmax = sockfd;
while(1) {
/*
sin_size = sizeof(struct sockaddr);
if((new_sockfd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
exit(1);
}
if((bytes = recv(new_sockfd, &buffor, sizeof(buffor), 0)) == -1) {
perror("recv");
exit(1);
}
printf("connection from: %s, recived: %s\n", inet_ntoa(their_addr.sin_addr), buffor);
*/
read_fds = master_fds;
if((select(fdmax+1, &read_fds, &write_fds, NULL, NULL)) == -1) {
perror("select");
exit(1);
}
for(i=0; i<fdmax; i++) {
if(FD_ISSET(i, &read_fds)) {
if(i==sockfd) {
sin_size = sizeof(struct sockaddr);
if((new_sockfd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
exit(1);
}
printf("server got connection from: %s, socket: %d\n", inet_ntoa(their_addr.sin_addr), new_sockfd);
FD_SET(status, &master_fds);
} else {
if((bytes = recv(new_sockfd, &buffor, sizeof(buffor), 0)) == -1) {
perror("recv");
exit(1);
}
printf("connection from: %s, recived: %s\n", inet_ntoa(their_addr.sin_addr), buffor);
}
}
}
}
system("pause");
close(sockfd);
close(new_sockfd);
return 0;
}
aby sprawdzić czy działa wystarczy połączyć się za pomocą telnetu na port 5000.
Wedle moich poszukiwań staje w miejscu
if(i==sockfd) { ...
Nie mam pojęcia jak rozwiązać ten problem, spędziłem nad nim prawie cały dzisiejszy dzień.
Nie do końca rozumiem koncepcje funkcji select.