/* * $ gcc -c selecttest.c -o selecttest.o * $ gcc selecttest.o -o selecttest */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <sys/select.h> #define PORT 16191 #define MAX_CONNECTION_NUM 1024 int socket_setnonblock(int fd) { int flags = fcntl(fd, F_GETFL); if (flags == -1) { printf("fcntl error %d\n", errno); return -1; } flags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) == -1) { printf("fcntl error %d\n", errno); return -1; } return 0; } int _socket(int domain, int type, int protocol) { return socket(domain, type, protocol); } int socket_bind(int sock, unsigned short int port) { printf("bind to port %d\n", port); struct sockaddr_in sock_addr; bzero(&sock_addr, sizeof(struct sockaddr_in)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); sock_addr.sin_port = htons(port); if(bind(sock, (struct sockaddr *) &sock_addr, sizeof(struct sockaddr)) == -1) { printf("bind error %d\n", errno); return -1; } return 0; } int socket_listen(int sock) { if (listen(sock, 50) == -1) { printf("listen error %d\n", errno); return -1; } return 0; } int max_fd(int fd, int *fdset, int fd_size) { int max = fd; if (fdset != NULL) { int i; for (i = 0; i < fd_size; i++) { if (fdset[i] != 0) { if (fdset[i] > max) { max = fdset[i]; } } } } return max; } void add_selecting_list(int fd, int* fdset, int* fd_size) { int i; for (i = 0; i < MAX_CONNECTION_NUM; i++) { if (fdset[i] == 0) { fdset[i] = fd; (*fd_size)++; break; } } } int main(int argc, char** argv) { char* var_port = NULL; int port; int fd = -1; int nfds = MAX_CONNECTION_NUM + 1; struct fd_set fds; struct timeval timeout = {3/* tv_sec: seconds */, 0 /* tv_usec: microseconds */}; int selected = -1; int fd_size = 0; int *fdset = NULL; var_port = getenv("port"); if (var_port == NULL) { char *new_var_port = NULL; printf("env variable=port not exists, set env variable port=%d\n", PORT); if (setenv("port", "16191", 0) != 0) { printf("set env variable error: %d\n", errno); return 1; } printf("set env variable ok\n"); new_var_port = getenv("port"); printf("env variable=port: %s\n", new_var_port); port = PORT; } else { port = atoi(var_port); } printf("port: %d\n", port); #ifdef USE_SOCK_NONBLOCK fd = _socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); #else fd = _socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { printf("socket error %d\n", errno); return 1; } else { printf("socket ok, socket: %d\n", fd); } socket_setnonblock(fd); #endif if (socket_bind(fd, port) == -1) { return -1; } if (socket_listen(fd) == -1) { return -1; } fdset = (int *) malloc(MAX_CONNECTION_NUM * sizeof(int)); nfds = max_fd(fd, fdset, MAX_CONNECTION_NUM) + 1; FD_ZERO(&fds); FD_SET(fd, &fds); while (1) { int i; printf("selecting...%d\n", fd_size + 1); printf("%d(server)\t", fd); for (i = 0; i < fd_size; i++) { printf("%d\t", fdset[i]); } printf("\n"); nfds = max_fd(fd, fdset, MAX_CONNECTION_NUM) + 1; FD_ZERO(&fds); FD_SET(fd, &fds); for (i = 0; i < fd_size; i++) { if (fdset[i] != 0) { FD_SET(fdset[i], &fds); } } selected = select(nfds, &fds, &fds, &fds, &timeout); if (selected == -1) { printf("select error: %d\n", errno); } else if (selected == 0) { printf("no selected...continue...\n"); } else { printf("selected %d\n", selected); if (FD_ISSET(fd, &fds)) { int new_fd = -1; struct sockaddr sock_addr; int addrlen = sizeof(struct sockaddr); new_fd = accept(fd, &sock_addr, &addrlen); if (new_fd == -1) { if (errno == EWOULDBLOCK) { } else { printf("accept error %d\n", errno); } continue; } else { printf("accept new connection from %d\n", new_fd); if (fd_size >= MAX_CONNECTION_NUM) { printf("refuse new connection from %d, max connection limit: %d\n", new_fd, MAX_CONNECTION_NUM); } else { add_selecting_list(new_fd, fdset, &fd_size); } } } for (i = 0; i < MAX_CONNECTION_NUM; i++) { if (fdset[i] != 0) { if (FD_ISSET(fdset[i], &fds)) { char buf[1024] = {0}; ssize_t nbytes = read(fdset[i], buf, 1024); if (nbytes == -1) { if (errno == ECONNRESET) { printf("connection from %d reset by peer, remove from selecting list\n", fdset[i]); fdset[i] = 0; fd_size--; } else if (errno == EWOULDBLOCK) { continue; } else { printf("read error %d\n", errno); } } else { printf("read data(%dbytes):%s\n", nbytes, buf); } } } } } } }
随便一点代码
猜你喜欢
转载自lobin.iteye.com/blog/2399438
今日推荐
周排行