epoll建立服务器

服务端

static int failover_read_from_tcp(int fd, char * buf, int size)
{
	int offset = 0;
	int bytes;
	int wanted = size;

	while (wanted > 0) {
		bytes = read(fd, buf+offset, wanted);
		if (bytes <= 0) {
			return -1;
		}
		wanted -= bytes;
		offset += bytes;
	}
	return 0;
}


static void *thread_listen(void *arg)
{
    int i = 0;
    int sockfd = -1; //server
    int epfd = -1;   //epoll
    int fd = -1;     //client
    int num = 0;
    struct sockaddr_in local_addr;
    struct sockaddr_in remote_address;  
    int len = sizeof(remote_address);
    struct epoll_event ev;
    struct epoll_event events[10];
    
    struct failover_request request;
    char *recvBuf;
        
	ms_task_set_name(THREAD_NAME_FAILOVER_LISTEN);
    
	if (global_failover_conf.task_listen_run)
	{
        request.buf= ms_malloc(MAX_DATA_SIZE);
        if (request.buf == NULL)
        {
            msdebug(DEBUG_WRN, "thread listen malloc failed");
            ms_task_quit(NULL);
	        return 0;
        }

        recvBuf = request.buf;
    
        sockfd =socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1)
        {
            msdebug(DEBUG_WRN, "thread listen socket creat failed");
            ms_free(request.buf);
            ms_task_quit(NULL);
	        return 0;
        }

        epfd = epoll_create(250);

        ev.data.fd = sockfd;
    	ev.events = EPOLLIN; //read
    	epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
        
        memset(&local_addr,0,sizeof(local_addr));
        local_addr.sin_family=AF_INET;
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port=htons(8000);
        
        if (bind(sockfd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == -1)
        {
            msdebug(DEBUG_WRN, "thread socket bind failed!");
            ms_free(request.buf);
            close(sockfd);
            ms_task_quit(NULL);
	        return 0;
        }

        if (listen(sockfd, 50) == -1)
        {
            msdebug(DEBUG_WRN, "thread socket listen failed!");
            ms_free(request.buf);
            close(sockfd);
            ms_task_quit(NULL);
	        return 0;
        }

        while (global_failover_conf.task_listen_run)
        {
            num = epoll_wait(epfd, events, 50, 500);
            

            if(num < 1) continue;
            msprintf("###### num:%d sockfd:%d ######\n", num, sockfd);
            for (i = 0; i < num; i++)
            {
                memset(request.buf, 0x0, SOCKET_DATA_MAX_SIZE);
                if (sockfd == events[i].data.fd && (events[i].events & EPOLLIN))
                {
        			fd = accept(sockfd, (struct sockaddr *)&remote_address, (socklen_t *)&len);
                    inet_ntop(AF_INET, (void*)&(remote_address.sin_addr), request.ipaddr, sizeof(request.ipaddr));
                    msprintf("###### fd:%d ip:%s #######\n", fd, request.ipaddr);
                    if (failover_read_from_tcp(fd, (char*)&request.header, sizeof(struct failover_header)) == 0)
        			{
        				
        				if(request.header.size > MAX_DATA_SIZE || request.header.condition != FAILOVER_CONDITION_CODE)
            			{
            				msprintf("##### unkonw connect ######\n");
            			}

            			if(request.header.size > 0)
            			{
            				if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
                            {
                                msprintf("##### read buf failed! #####\n");
                            }            
            				
            				if(request.header.size < SOCKET_DATA_MAX_SIZE)
            					recvBuf[request.header.size] = '\0';

                            msprintf("###### recv 111 buf :%s ########\n", recvBuf);
            			}
        			}

                    ev.data.fd = fd;
                    ev.events = EPOLLIN;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,ev.data.fd,&ev);
                }
                else if (events[i].events & EPOLLIN)
                {
                    msprintf("###### old fd:%d ######\n", events[i].data.fd);
                    if (events[i].data.fd < 0) continue;
                    
                    if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
                    {
                        //disconnect
                        msprintf("##### dis connect 000 ######\n");
                        ev.data.fd = events[i].data.fd;
                        ev.events = EPOLLIN; //read
                        epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
                        close(events[i].data.fd);
                        events[i].data.fd = -1;
                        continue;
                    }
                    msprintf("##### size:%d #####\n", request.header.size);
                    if(request.header.size > MAX_DATA_SIZE || request.header.condition != FAILOVER_CONDITION_CODE)
        			{
        				msprintf("##### unkonw connect ######\n");
                        ev.data.fd = events[i].data.fd;
                        ev.events = EPOLLIN; //read
                        epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
                        close(events[i].data.fd);
                        events[i].data.fd = -1;
                        continue;
        			}

                    if(request.header.size > 0)
        			{
        				if (failover_read_from_tcp(fd, recvBuf, request.header.size) < 0)
                        {
                            msprintf("##### dis connect 111 ######\n");
                            ev.data.fd = events[i].data.fd;
                            ev.events = EPOLLIN; //read
                            epoll_ctl(epfd, EPOLL_CTL_DEL, ev.data.fd, &ev);
                            close(events[i].data.fd);
                            events[i].data.fd = -1;
                        }
                        else
                        {

                            if(request.header.size < SOCKET_DATA_MAX_SIZE)
                            {            
            					recvBuf[request.header.size] = '\0';
                            }

                            msprintf("###### recv 222 buf:%s ########\n", recvBuf);
                        }
        			}
                }
                else
                {
                    msprintf("### else fd:%d %d ####\n", events[i].data.fd, events[i].events);
                }
                
                    
            }
        }


        ms_free(request.buf);
        close(sockfd);
	}
	
	ms_task_quit(NULL);
	return 0;	
}

客户端

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAXLINE 1024

#define MAX_DATA_SIZE	            (1*1024*1024)//1M
#define FAILOVER_CONDITION_CODE		0x20120610

struct failover_header{
    int condition;
	int type;
	int from;
    int req;
	int size;
	int crc;
};

struct failover_packet{
    struct failover_header header;
    char buf[MAX_DATA_SIZE];
};

int main(int argc,char **argv)
{
    char *servInetAddr = "192.168.2.143";
    int socketfd;
    struct sockaddr_in sockaddr;
    char recvline[MAXLINE], sendline[MAXLINE];
    int n;
    
    char *sendBuf = NULL;
    sendBuf = malloc(MAX_DATA_SIZE+sizeof(struct failover_header));
    
    struct failover_header *header;

    if(argc != 2)
    {
        printf("client <ipaddress> \n");
        //exit(0);
    }

    socketfd = socket(AF_INET,SOCK_STREAM,0);
    memset(&sockaddr,0,sizeof(sockaddr));
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons(8000);
    inet_pton(AF_INET,servInetAddr,&sockaddr.sin_addr);
    if((connect(socketfd,(struct sockaddr*)&sockaddr,sizeof(sockaddr))) < 0 )
    {
        printf("connect error %s errno: %d\n",strerror(errno),errno);
        exit(0);
    }

    printf("send message to server\n");

    //fgets(sendline,1024,stdin);
    snprintf(sendline, sizeof(sendline), "%s", "abc");
    
    
    header = (struct failover_header *)sendBuf;
    header->condition = FAILOVER_CONDITION_CODE;
    
    header->type = 1;
	header->from = 2;
    header->req = 3;
	header->size = strlen(sendline);
	header->crc = 0;
    memcpy(sendBuf+sizeof(struct failover_header), sendline, strlen(sendline));
    printf(" send len:%d %d \n", sizeof(struct failover_header),header->size);
    if((send(socketfd,sendBuf,header->size+sizeof(struct failover_header),0)) < 0)
    {
        printf("send mes error: %s errno : %d",strerror(errno),errno);
        exit(0);
    }
    
    sleep(1);
   #if 1
    snprintf(sendline, sizeof(sendline), "%s", "efg");
    memcpy(sendBuf+sizeof(struct failover_header), sendline, 3);
    //*(sendBuf+sizeof(struct failover_header)+3) = '\0';
    printf("###### 111 %s ######\n", sendBuf+sizeof(struct failover_header));
    header->size = 3;
    if((send(socketfd,sendBuf,header->size+sizeof(struct failover_header),0)) < 0)
    {
        printf("send mes error: %s errno : %d",strerror(errno),errno);
        exit(0);
    }
    #endif
    
    free(sendBuf);
    close(socketfd);
    printf("exit\n");
    exit(0);
}

猜你喜欢

转载自blog.csdn.net/y7u8t6/article/details/84344061