TCP & EPOLL客户端程序

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/epoll.h>
#include <errno.h>
#include <pthread.h>

#define MAX_EPOLL_SIZE 20
#define MAX_EPOLL_TIMEOUT 500  //ms
#define MAX_BUFF_SIZE 100 //接受包大于100字节时,循环接收
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int epoll_fd = 0;
int set_fd_nonblocking(int fd);
int init_epoll();
int add_epoll_ctl(int fd);
int del_epoll_ctl(int fd);
int init_network();
void * sendMsg_info(void *data);
void init_sendMsg_pthread(int *  net_fd);

void do_tcp(int client_fd,struct sockaddr_in addr,char * buff,int len)
{
	printf(" buff is : %s , len = %d\n",buff,len);
}

int set_fd_nonblocking(int fd)
{
	int opts = fcntl(fd, F_GETFL);
	if(0 > opts) 
	{
		printf("fcntl failed !\n");
		return -1;
	}
	opts = opts | O_NONBLOCK;
	return fcntl(fd, F_SETFL, opts);
}

int init_epoll()
{
	epoll_fd = epoll_create(MAX_EPOLL_SIZE);
	if(epoll_fd < 0)
	{
		printf("epoll_create failed !\n");
		return -1;
		
	}

	return 0;
}

int add_epoll_ctl(int fd)
{
	struct epoll_event event;
	
	memset(&event,0,sizeof(event));
	event.events = EPOLLIN | EPOLLET;
	event.data.fd = fd;
	
	if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,fd,&event) < 0)
	{
		printf("epoll_ctl EPOLL_CTL_ADD failed !\n");
		return -1;
	}
	
	return 0;
}

int del_epoll_ctl(int fd)
{
	struct epoll_event event;
	
	memset(&event,0,sizeof(event));
	event.events = EPOLLIN | EPOLLET;
	event.data.fd = fd;
	
	if(epoll_ctl(epoll_fd,EPOLL_CTL_DEL,fd,&event) < 0)
	{
		printf("epoll_ctl EPOLL_CTL_DEL failed !\n");
		return -1;
	}
	
	return 0;
}

int init_network()
{
	int ret = -1;
	int len = sizeof(int);
	int tmp;
	int net_fd = socket(AF_INET,SOCK_STREAM,0);
	struct sockaddr_in addr;
	socklen_t sock_len = sizeof(struct sockaddr_in);
	int iRet = 0;
	int error = 0;

	if(net_fd < 0)
	{
		printf("tcp_client init_network failed!\n");
		return -1;
	}

	ret = set_fd_nonblocking(net_fd);
	if(ret < 0)
	{
		close(net_fd);
		net_fd = -1;
		return -1;
	}
	
	if(setsockopt(net_fd,SOL_SOCKET,SO_REUSEADDR,&tmp,sizeof(tmp)))
	{
		printf("setsockopt failed !\n");
		close(net_fd);
		return -1;
	}
	
	bzero(&addr,sizeof(addr));
	addr.sin_port = htons(8888);
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr("10.0.12.203");
	
	iRet = connect(net_fd,(struct sockaddr *)&addr,sock_len);	

	if(iRet)
	{
		if (errno != EINPROGRESS)  
        {
			close(net_fd);
			net_fd = -1;
        	printf("connect failed!\n");
			return net_fd;
		}
		
		getsockopt(net_fd, SOL_SOCKET, SO_ERROR, &error, &len);
		if (0 == error)
		{
			iRet = 0;
		}
		else
		{
			printf("connect failed!\n");
		}
		
	}


	if(iRet == 0)
	{
		ret = add_epoll_ctl(net_fd);
		if(ret < 0)
		{
			close(net_fd);
			net_fd = -1;
			return -1;
		}
		printf("connect success !\n");
	}
	else
	{
		close(net_fd);
		net_fd = -1;
	}

	return net_fd;
}

void * sendMsg_info(void *data)
{
	int fd = 0;
	struct sockaddr_in addr;
	char *buff = "hello tcp server!, I'm tcp client.";
	size_t len = strlen(buff);
	int send_len = 0;

	if(NULL == data)
	{
		printf("data is NULL\n");
		return NULL;
	}

	bzero(&addr,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8888);
	addr.sin_addr.s_addr = inet_addr("10.0.12.203");

	fd = *(int *)data;
	while(1)
	{
		send_len = send(fd,(void *)buff,len,0);
		sleep(1);
	}
	return NULL;
}

void init_sendMsg_pthread(int * net_fd)
{
	pthread_t tid;
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	pthread_create(&tid,&attr,sendMsg_info,net_fd );
	pthread_attr_destroy(&attr);

	return ;
}

int main()
{
	struct epoll_event events[MAX_EPOLL_SIZE];
	int epoll_num = 0;
	int i = 0;
	int net_fd = 0;
	struct sockaddr_in addr;
	socklen_t sock_len = sizeof(struct sockaddr_in);
	char *buff = NULL;
	char *buff_new = NULL;
	int buff_size = MAX_BUFF_SIZE;
	int len = 0;
	int recvlen = 0;

	bzero(events,MAX_EPOLL_SIZE);

	while(epoll_fd <= 0)
	{
		init_epoll();
		sleep(1);
	}

	while(net_fd <= 0)
	{
		net_fd = init_network();
		sleep(1);
	}

	init_sendMsg_pthread(&net_fd); 

	while(1)
	{
		epoll_num = epoll_wait(epoll_fd,events,MAX_EPOLL_SIZE,MAX_EPOLL_TIMEOUT);
		for(i=0;i<epoll_num;i++)
		{
			if(events[i].data.fd == net_fd)
			{
				pthread_mutex_lock(&mutex);
				buff = (char *)malloc(MAX_BUFF_SIZE);
				if(NULL == buff)
				{
					printf("malloc failed!\n");
					pthread_mutex_unlock(&mutex);
					break;
				}
				memset(buff,0,MAX_BUFF_SIZE);

				len = recv(events[i].data.fd,buff,MAX_BUFF_SIZE,0);
				recvlen = len;

				if((len < 0 && errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) || len == 0)
				{
					del_epoll_ctl(events[i].data.fd);
					close(events[i].data.fd);
				}
				else if(len > 0)
				{
					if(len == MAX_BUFF_SIZE)
					{
						while(len == MAX_BUFF_SIZE)
						{
							len = 0;
							buff_size += MAX_BUFF_SIZE;
							buff_new = (char *)realloc(buff,buff_size);
							if(buff_new == NULL)
							{
								printf("realloc failed!\n");
								break;
							}
							buff = buff_new;
							len = recv(events[i].data.fd,&buff[recvlen],MAX_BUFF_SIZE,0);
							if(len > 0)
							{
								recvlen += len;
							}
							else if((len < 0 && errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN) || len == 0)
							{
								del_epoll_ctl(events[i].data.fd);
								close(events[i].data.fd);
							}
						}

						do_tcp(events[i].data.fd,addr,buff,recvlen);
					}
					else
					{
						do_tcp(events[i].data.fd,addr,buff,recvlen);
					}

				}
				
				free(buff);
				buff = NULL;
				pthread_mutex_unlock(&mutex);
			}
			else
			{
				//do noting
			}
		}

	}
	
	del_epoll_ctl(net_fd);
	close(net_fd);
	close(epoll_fd);
	return 0;
}
发布了5 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jiust12138/article/details/102752981