#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/time.h>
#include <arpa/inet.h>
#include <poll.h>
#include <sys/epoll.h>
#define backlog 5
#define BUFFSIZE 1024
int epoll_add(int epfd, int fd)
{
struct epoll_event ev = {
.events = EPOLLIN,
.data.fd = fd
};
if(-1 == epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev))
{
perror("epoll_add");
return -1;
}
return 0;
}
int epoll_del(int epfd, int fd)
{
if(-1 == epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL))
{
perror("epoll_del");
return -1;
}
return 0;
}
int create_listenfd(const char *ip, unsigned short port)
{
/*1.创建监听套接字*/
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
if(-1 == listenfd)
{
perror("socket");
return -1;
}
/*填充服务器地址协议、ip地址和端口号*/
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = (ip == NULL ? INADDR_ANY :inet_addr(ip));
/*2.给本地套接字绑定协议、ip和端口*/
if(-1 == bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)))
{
perror("bind");
close(listenfd);
return -1;
}
printf("bind success!\n");
/*3.监听*/
if(-1 == listen(listenfd, backlog))
{
perror("listen");
close(listenfd);
return -1;
}
printf("listening ...\n");
return listenfd;
}
int main(int argc, char *argv[])
{
int listenfd = create_listenfd(NULL,atoi(argv[2]));
if(-1 == listenfd)
{
return 0;
}
char buff[BUFFSIZE];
int recvbytes, sendbytes;
int epfd;
epfd = epoll_create(10);
if(-1 == epfd)
{
perror("epoll_create");
close(listenfd);
exit(EXIT_FAILURE);
}
epoll_add(epfd, STDIN_FILENO);
epoll_add(epfd, listenfd);
struct epoll_event revents[10];
while(1)
{
int ret = epoll_wait(epfd, revents, 10, 3*1000);
if(-1 == ret)
{
perror("epoll_wait");
break;
}
else if(0 == ret)
{
printf("timeout...\n");
}
else
{
for(int i = 0; i <= ret; i++)
{
int fd = revents[i].data.fd;
if(revents[i].events & EPOLLIN)
{
if(fd == STDIN_FILENO)
{
fgets(buff, sizeof(buff), stdin);
printf("gets:%s",buff);
}
else if(fd == listenfd)
{
int connectfd = accept(listenfd, NULL, NULL);
if(-1 == connectfd)
{
perror("accept");
close(listenfd);
return 0;
}
printf("A new client(fd=%d) is connect success!\n", connectfd);
epoll_add(epfd, connectfd);
}
else
{
recvbytes = recv(fd, buff, sizeof(buff), 0);
if(recvbytes < 0)
{
perror("recv");
epoll_del(epfd, fd);
close(fd);
break;
}
if(recvbytes == 0)
{
printf("client(fd=%d) is closed!\n", fd);
epoll_del(epfd, fd);
close(fd);
break;
}
printf("server recv from client(fd=%d):%s", fd, buff);
}
}
}
}
}
/*6.关闭套接字*/
close(listenfd);
return 0;
}