[linux系统编程]网络编程 服务器多路复用

作为一个命令台使用的服务器:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <math.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h> 
#include <sys/msg.h>
#include <pthread.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 10000
#define LISTEN_NUM      10
#define MAX_PACKET_SIZE	(1024)

static int connect_fd[LISTEN_NUM];

int main()
{
	int sPort = PORT;
    int sListen = 0;
    int sAccept = 0;
    unsigned int sLen = 0;
    int sReuseaddr = 1;
    int sSocketopt = 0;
    struct sockaddr_in ser;
    struct sockaddr_in cli;
    int ret = -1;
    int iloop = 0;
    int kloop = 0;
    int jloop = 0;
    int count_id = 0;    
    char buf[MAX_PACKET_SIZE] = {0};
    fd_set fdsr;
    int max_sock;
    struct timeval timeout;
    sLen = sizeof(cli);
    max_sock = sListen;
    
    sListen = socket(AF_INET, SOCK_STREAM, 0);
    if(sListen < 0)
    {
        printf("cmd_server socket() failure!\n");
        return (-1);
    }
    
    sSocketopt = setsockopt(sListen, SOL_SOCKET, SO_REUSEADDR, &sReuseaddr, sizeof(int));
    if(sSocketopt < 0)
    {
        printf("cmd_server setsockopt() failure!\n");
        return (-1);
    }
    
    ser.sin_family = AF_INET;
    ser.sin_port = htons(sPort);
    ser.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(ser.sin_zero, '\0', sizeof(ser.sin_zero));
    
    if(bind(sListen, (struct sockaddr*)&ser, sizeof(ser)) < 0)
    {
        printf("cmd_server bind() failure!\n");
        return (-1);
    }
    
    if(listen(sListen, LISTEN_NUM) < 0)
    {
        printf("cmd_server listen() failure!\n");
        return (-1);
    }
	
	sLen = sizeof(cli);
    max_sock = sListen;
	
    for (iloop = 0; iloop < LISTEN_NUM; iloop++)
    {
          connect_fd[iloop] = 0;
          
    }
    
    for(;;)
    {
    	timeout.tv_sec  = 3;
    	timeout.tv_usec = 0;
        FD_ZERO(&fdsr);
        FD_SET(sListen, &fdsr);
        
        for (iloop = 0; iloop < LISTEN_NUM; iloop++)
        {
            if (connect_fd[iloop] != 0)
            {
                FD_SET(connect_fd[iloop], &fdsr);
            }
        }
        
        ret = select(max_sock + 1, &fdsr, NULL, NULL, &timeout);
        if (ret == 0)
        {
        	printf("SERVER select time out\n");
            continue;
        }
        else if (ret < 0)
        {
			printf("SERVER select failured\n");
            continue;
        }
        
        for (kloop = 0; kloop < LISTEN_NUM; kloop++)
        {
            if (FD_ISSET(connect_fd[kloop], &fdsr))
            {
            	memset(buf, 0x00, sizeof(buf));
            	ret = recv(connect_fd[kloop], &buf, sizeof(buf), 0);
				if(ret <= 0)
				{
					printf("Close socket\n");
					close(connect_fd[kloop]);
					FD_CLR(connect_fd[kloop], &fdsr);
					connect_fd[kloop] = 0;
				}
				else
				{
					//处理程序
				}
			}
        }
        
        if (FD_ISSET(sListen, &fdsr))
		{
			sAccept = accept(sListen, (struct sockaddr *)&cli, (unsigned int*)&sLen);
			if (sAccept <= 0)
			{
				printf("cmd_server accept() failure!  errno=%d, slisten=%d\n",errno,sListen);
				usleep(5000);
				continue;
			}
			
			for(count_id = 0; count_id < LISTEN_NUM; count_id++)  
			{
				if(connect_fd[count_id] == 0)
				{
					break;
				}
			}
			
			if (count_id == LISTEN_NUM)  
			{
				printf("max connections arrive, exit!!!\n");

				for (jloop = 0; jloop < LISTEN_NUM; jloop++)
				{
					if (connect_fd[jloop] != 0)
					{
						connect_fd[jloop] = 0;
						FD_CLR(connect_fd[jloop], &fdsr);
						close(connect_fd[jloop]);
					}
				}
				usleep(5000);
				continue;
			}
			
			if (sAccept > max_sock)
			{
				max_sock = sAccept;
			}

			connect_fd[count_id] = sAccept;
			printf("Accept OK!  count_id=%d\n", count_id);
		}
	}
	
	return 0;
}


猜你喜欢

转载自blog.csdn.net/mingtianyueni/article/details/18816549
今日推荐