随便一点代码

/*
 * $ 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