diff --git a/mysever.c b/mysever.c new file mode 100644 index 0000000000000000000000000000000000000000..4fd1c0465c9a71a33cd2ceaa059148f78fb4c236 --- /dev/null +++ b/mysever.c @@ -0,0 +1,169 @@ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include <netinet/in.h> +#include <ctype.h> +#include <arpa/inet.h> + +#include <fcntl.h> +#include <netdb.h> + +#include <string.h> +#include <strings.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> +#define MAXFD 2 + +int main(int argc, char ** argv) +{ + int sockfd, newsockfd, portno; // clilen; + char buffer[256]; + struct sockaddr_in serv_addr, cli_addr; + socklen_t clilen; + int n; + char * c;// + + if (argc < 3) + { + fprintf(stderr, "usage: %s ip port\n", argv[0]); + return 0; + } + + /* Create TCP socket */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) + { + perror("ERROR opening socket"); + exit(EXIT_FAILURE); + } + + // reuse the socket if possible + int const reuse = 1; + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) + { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + + portno = atoi(argv[2]); + + /* Create address we're going to listen on (given port number) + - converted to network byte order & any IP address for this machine */ + bzero((char *)&serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY;//differ + serv_addr.sin_port = htons(portno); // store in machine-neutral format + + /* Bind address to the socket */ + if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) + { + perror("ERROR on binding"); + exit(EXIT_FAILURE); + } + + /* Listen on socket - means we're ready to accept connections - + incoming connection requests will be queued */ + listen(sockfd, 5); + + clilen = sizeof(cli_addr); + + /* Accept a connection - block until a connection is ready to + be accepted. Get back a new file descriptor to communicate on. */ + /*newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); + if (newsockfd < 0) + { + perror("ERROR on accept"); + exit(EXIT_FAILURE); + }*/ + + // initialise an active file descriptors set + fd_set masterfds; + FD_ZERO(&masterfds); + FD_SET(sockfd, &masterfds); + // record the maximum socket number + int maxfd = sockfd; + + while (1) + { + // monitor file descriptors + fd_set readfds = masterfds; + if (select(FD_SETSIZE, &readfds, NULL, NULL, NULL) < 0) + { + perror("select"); + exit(EXIT_FAILURE); + } + + // loop all possible descriptor + for (int i = 0; i <= maxfd; ++i) + // determine if the current file descriptor is active + if (FD_ISSET(i, &readfds)) + { + // create new socket if there is new incoming connection request + if (i == sockfd) + { + int newsockfd = accept(sockfd, (struct sockaddr *)&cliaddr, &clilen); + if (newsockfd < 0) + perror("accept"); + else + { + // add the socket to the set + FD_SET(newsockfd, &masterfds); + // update the maximum tracker + if (newsockfd > maxfd) + maxfd = newsockfd; + // print out the IP and the socket number + /*char ip[INET_ADDRSTRLEN]; + printf( + "new connection from %s on socket %d\n", + // convert to human readable string + inet_ntop(cliaddr.sin_family, &cliaddr.sin_addr, ip, INET_ADDRSTRLEN), + newsockfd + );*/ + } + } + // a message is sent from the client + else + { /* Read characters from the connection, then process */ + char buff[256]; + int n = read(i, buff, 256); + if (n <= 0) + { + if (n < 0) + perror("read"); + else + printf("socket %d close the connection\n", i); + close(i); + FD_CLR(i, &masterfds); + } + // write back to the client + else if (write(i, buff, n) < 0) + { + perror("write"); + close(i); + FD_CLR(i, &masterfds); + } + } + } + + + + if (!strncmp(buffer, "GOODBYE-CLOSE-TCP", 17)) + break; + + /*c = buffer; + while (*c) + { + *c = toupper(*c); + ++c; + }*/ + + + + /* close socket */ + //close(sockfd); + + return 0; +}