还有很多问题,等待更新吧,哎,凡事需要自己写一遍,道理谁都懂;写完再和别人的代码对比。
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <error.h>
#include <strings.h>
#include <sys/types.h>
#include <pthread.h>
#define MAX 65536
void echo(int sockfd, int epollfd)
{
char buf[3];
bzero(buf,3);
int len = recv(sockfd, buf, 1024, 0);
if (len < 0)
{
perror("RECV : ");
return;
}
else if (len == 0)
{
fprintf(stderr, "client exit ... \n");
/*del event*/
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLERR;
ev.data.fd = sockfd;
if (epoll_ctl(epollfd, EPOLL_CTL_DEL, sockfd, &ev) < 0)
{
perror("EPOLL DEL : ");
return;
}
return;
}
//send
printf("recv...\n");
if (send(sockfd, buf, len, 0) != len)
{
perror("SEND : ");
return ;
}
}
void* run(void *arg)
{
int* tmp = (int *)arg;
int epollfd = *tmp;
while (1)
{
struct epoll_event events[MAX];
int nfds = epoll_wait(epollfd, events, MAX, -1);
printf("nfds = %d\n", nfds);
//nt handle
for (int i=0; i<nfds; ++i)
{
int readyd = events[i].data.fd;
if (events[i].events & EPOLLIN)
{
echo(readyd, epollfd);
}
}
}
return (void*)0;
}
int main(void)
{
int listenfd;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0)
{
perror("SOCKET : ");
return 1;
}
int reuse = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
struct sockaddr_in listen_addr;
bzero(&listen_addr,sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(12345);
if ( bind(listenfd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0)
{
perror("BIND : ");
return 1;
}
if (listen(listenfd,5) < 0)
{
perror("LISTEN : ");
return 1;
}
//printf("Listening... on IP , port %d\n",12345);
printf("Listening... \n");
// I/O- multiplexing
int epollfd = epoll_create1(0);
if (epollfd < 0)
{
perror("EPOLL : ");
return 1;
}
pthread_t pid;
if (pthread_create(&pid, NULL, run, (void *)&epollfd) < 0)
{
perror("PTHREAD CREATE : ");
return 1;
}
//accept
struct sockaddr_in cli_addr;
int len =sizeof(cli_addr);
int acceptfd;
int cnt = 0;
while (1)
{
acceptfd = accept(listenfd, (struct sockaddr *)&cli_addr, &len);
if (acceptfd < 0)
{
perror("ACCEPT : ");
return 1;
}
else
{
cnt++;
fprintf(stderr, "accept %d client\n",cnt);
//add to epoll_wait
struct epoll_event event;
event.events = EPOLLIN | EPOLLERR | EPOLLHUP;
event.data.fd = acceptfd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, acceptfd, &event);
}
}
if (pthread_join(pid,NULL) < 0)
{
perror("PTHREAD JOIN : ");
return 1;
}
return 0;
}
还有很多工作没做。。。
1. 压力测试。。。
2. 其他各种测试。。。
3. 另,上诉代码更改下可以测试epoll LT模式,其中如果数据没有处理,会一直触发。