#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 opts = fcntl(fd, F_GETFL);
if(0 > opts)
{
printf("fcntl failed !\n");
return -1;
}
opts = opts | O_NONBLOCK;
return fcntl(fd, F_SETFL, opts);
}
void do_tcp(int client_fd,struct sockaddr_in addr,char * buff,int len)
{
printf(" buff is : %s , len = %d\n",buff,len);
}
int init_network()
{
struct sockaddr_in addr;
int tmp = 1;
bzero(&addr,sizeof(addr));
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd < 0)
{
printf("create socket failed !\n");
return -1;
}
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&tmp,sizeof(tmp)))
{
printf("setsockopt failed !\n");
close(fd);
return -1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(fd,(struct sockaddr *)&addr,sizeof(addr)) < 0)
{
printf("bind failed !\n");
close(fd);
return -1;
}
if(listen(fd,20) < 0)
{
printf("listen failed !\n");
close(fd);
return -1;
}
if(set_fd_nonblocking(fd) < 0)
{
printf("set_fd_nonblocking failed !\n");
close(fd);
return -1;
}
return fd;
}
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 main()
{
int i = 0;
int fd = 0;
int client_fd = 0;
char *buff = NULL;
char *buff_new = NULL;
int buff_size = MAX_BUFF_SIZE;
int len = 0;
int recvlen = 0;
struct epoll_event events[MAX_EPOLL_SIZE];
int event_num = 0;
struct sockaddr_in addr;
bzero(&addr,sizeof(addr));
socklen_t sock_len = sizeof(struct sockaddr_in);
memset(events,0,MAX_EPOLL_SIZE);
while(fd <= 0)
{
fd = init_network();
sleep(1);
}
while(epoll_fd <= 0)
{
init_epoll();
sleep(1);
}
buff = (char *)malloc(MAX_BUFF_SIZE);
if(NULL == buff)
{
printf("malloc failed!\n");
}
add_epoll_ctl(fd);
while(1)
{
event_num = epoll_wait(epoll_fd,events,MAX_EPOLL_SIZE,MAX_EPOLL_TIMEOUT);
printf("event_num = %d\n",event_num);
for(i=0;i<event_num;i++)
{
client_fd = 0;
len = 0;
if(events[i].data.fd == fd) //new connect, do accept
{
client_fd = accept(fd,(struct sockaddr *)&addr,&sock_len);
if(client_fd < 0)
{
printf("accept failed !\n");
continue;
}
set_fd_nonblocking(client_fd);
add_epoll_ctl(client_fd);
}
else if(events[i].events & EPOLLIN) //do recv
{
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);
}
}
}
pthread_mutex_destroy(&mutex);
del_epoll_ctl(fd);
close(fd);
close(epoll_fd);
return 0;
}
TCP & EPOLL服务器编程
猜你喜欢
转载自blog.csdn.net/jiust12138/article/details/102563896
今日推荐
周排行