#include #include #include #include #include #include #include #include #include #include #include int setup_tcp_socket(short int port) { /* server address */ struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(struct sockaddr_in)); socklen_t addrlen = sizeof(struct sockaddr_in); /* for setsockopt() SO_REUSEADDR, below */ int yes = 1; int listener = -1; if((listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { perror("Server-socket()"); exit(1); } printf("Server-socket() is OK... fd %d\n", listener); /*"address already in use" error message */ if(setsockopt(listener , SOL_SOCKET , SO_REUSEADDR , &yes , sizeof(int)) == -1) { perror("Server-setsockopt()"); exit(1); } printf("Server-setsockopt() is OK...\n"); /* bind */ serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(port); serveraddr.sin_addr.s_addr = INADDR_ANY; // memset(&(serveraddr.sin_zero), '\0', 8); if(bind(listener, (struct sockaddr *)&serveraddr, addrlen) == -1) { perror("Server-bind()"); exit(1); } printf("Server-bind() is OK...\n"); /* listen */ if(listen(listener, 10) == -1) { perror("Server-listen()"); exit(1); } printf("Server-listen() is OK...\n"); return listener; } int main(int argc, char * argv[]) { if (argc < 2) { fprintf (stderr, "usage: %s port\n", argv[0]); exit(1); } short int port = atoi(argv[1]); printf ("port : %d\n", port); /* client address */ struct sockaddr_in clientaddr; memset(&clientaddr, 0, sizeof(struct sockaddr_in)); /* master file descriptor list */ fd_set master; /* temp file descriptor list for select() */ fd_set read_fds; /* maximum file descriptor number */ int fdmax; /* listening socket descriptor */ // int listener = open ("/tmp/bla", O_RDONLY); int listener; int newfd; /* buffer for client data */ char buf[6]; int nbytes; socklen_t addrlen; int i, j; /* Now we set variables */ listener = setup_tcp_socket (port); /* clear the master and temp sets */ FD_ZERO(&master); FD_ZERO(&read_fds); /* add the listener to the master set */ FD_SET(listener, &master); /* keep track of the biggest file descriptor */ fdmax = listener; /* so far, it's this one*/ int times_going_in_select = 0; /* loop */ for(;;) { /* copy it */ read_fds = master; if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("Server-select() error lol!"); exit(1); } times_going_in_select++; // printf("Server-select() is OK... message received\n"); /*run through the existing connections looking for data to be read*/ for(i = 0; i <= fdmax; i++) { if(FD_ISSET(i, &read_fds)) { /* we got one... */ if(i == listener) { printf("new connection"); /* handle new connections */ addrlen = sizeof(clientaddr); if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) { perror("Server-accept()"); } else { printf("Server-accept() is OK...\n"); FD_SET(newfd, &master); /* add to master set */ if(newfd > fdmax) { /* keep track of the maximum */ fdmax = newfd; } printf("%s: New connection from %s on socket %d\n" , argv[0], inet_ntoa(clientaddr.sin_addr), newfd); } } else { /* handle data from a client */ if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { /* got error or connection closed by client */ if(nbytes == 0) /* connection closed */ printf("%s: socket %d hung up\n", argv[0], i); else perror("recv() error lol!"); /* close it... */ close(i); /* remove from master set */ FD_CLR(i, &master); } else { printf("received message: %s (%d going in select function)\n", buf, times_going_in_select); /* we got some data from a client*/ for(j = 0; j <= fdmax; j++) { /* send to everyone! */ if(FD_ISSET(j, &master)) { #if 0 /* except the listener and ourselves */ if(j != listener && j != i) #endif /* except the listener */ if(j != listener) { if(send(j, buf, nbytes, 0) == -1) perror("send() error lol!"); } } } } } } } } return EXIT_SUCCESS; }