程序功能:监听tcp客户端连接,并用epoll监听这些客户端发送的数据,相当于一个日志接收器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <errno.h>
#include <vector>
#include <pthread.h>
#define MAX_EVENT 20
#define BUFF_SIZE 100*1024
//epoll句柄
int epfd = 0;
void add_epoll_socket(int fd, EPOLL_EVENTS et);
void delete_epoll_socket(int fd, EPOLL_EVENTS et);
int main(int argc, char *argv[])
{
if(argc!=2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
//建立服务端socket,监听端口:argv[1]
int serv_sock=socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
{
printf("socket() failed, errno=%d\n", errno);
exit(1);
}
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1)
{
printf("bind() failed, errno=%d\n", errno);
exit(1);
}
if(listen(serv_sock, 5)==-1)
{
printf("listen() failed, errno=%d\n", errno);
exit(1);
}
//创建epoll句柄
epfd = epoll_create(MAX_EVENT);
if (epfd < 0)
{
printf("epoll_create() failed, errno=%d, epfd=%d\n", errno, epfd);
exit(1);
}
add_epoll_socket(serv_sock, EPOLLIN);
int i, ret, len, fd;
struct epoll_event events[MAX_EVENT];
char buff[BUFF_SIZE] = {0};
char log[BUFF_SIZE] = {0};
char *begin, *end;
while (1)
{
//监听socket事件
ret = epoll_wait(epfd, events, MAX_EVENT, 200);
for (i = 0; i < ret; i++)
{
fd = events[i].data.fd;
if (fd == serv_sock)
{
struct sockaddr_in client_addr;
socklen_t addr_size = sizeof(sockaddr_in);
int client_sock = accept(fd, (struct sockaddr*)&client_addr, &addr_size);
if(client_sock == -1)
{
printf("accept() failed, errno=%d\n", errno);
continue;
}
char *addr = inet_ntoa(client_addr.sin_addr);
printf("client_sock=%d, addr=%s\n", client_sock, addr);
//不监听回送连接
if (strcmp(addr, "127.0.0.1") != 0)
{
add_epoll_socket(client_sock, EPOLLIN);
}
}
else
{
//从缓冲区读数据,实际上需要注意tcp有粘包问题
len = recv(fd, buff+strlen(buff), BUFF_SIZE-strlen(buff), 0);
//recv返回0说明socket关闭
if (len == 0)
{
delete_epoll_socket(fd, EPOLLIN);
close(fd);
continue;
}
printf("buff='%s'\n", buff);
memset(buff, 0, BUFF_SIZE);
}
} //for
} //while (1)
close(epfd);
close(serv_sock);
return 0;
}
void add_epoll_socket(int fd, EPOLL_EVENTS evt)
{
struct epoll_event et;
et.data.fd = fd;
et.events = evt;
epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &et);
}
void delete_epoll_socket(int fd, EPOLL_EVENTS evt)
{
struct epoll_event et;
et.data.fd = fd;
et.events = evt; //fd可读事件
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &et);
}