#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/select.h>
#include <sys/epoll.h>
#define SA struct sockaddr
int main(int argc, const char *argv[])
{
//socket
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
perror("fail to socket");
exit(1);
}
struct sockaddr_in myaddr,peeraddr;
myaddr.sin_family=AF_INET;
myaddr.sin_port=htons(50000);
myaddr.sin_addr.s_addr=inet_addr("0.0.0.0");
socklen_t len=sizeof(peeraddr);
char buf[128];
int confd;
//bind
int ret_bind=bind(sockfd,(SA*)&myaddr,sizeof(myaddr));
if(ret_bind<0)
{
perror("fail to bind");
exit(1);
}
int ret_lis=listen(sockfd,5);
if(ret_lis<0)
{
perror("fail to listen ");
exit(1);
}
// man 7 epoll
//select 闂
//锛�1锛� 鍙嶅杩涜鐢ㄦ埛绌洪棿鍜屽唴鏍哥┖闂寸殑鏁版嵁浜ゆ崲 锛堝~鍏呰〃锛�
//锛�2锛� 鏃犳剰涔夌殑閬嶅巻 锛坕<= maxfd锛�
//epoll 涓€娆℃坊鍔犳枃浠舵弿杩扮锛屼笉闇€瑕佸啀娣诲姞浜�
//灏辩华鐨勭粨鏋滃皢杩斿洖鍒颁竴涓暟缁勪腑锛屼笉闇€瑕侀亶鍘�
//select 缂虹偣 鎭板ソ姝f槸 epoll 鐨勪紭鐐�
// 閫傚悎杈圭紭瑙﹀彂鍜屾潯浠惰Е鍙戠殑
// 閫傚悎鐩戞帶 澶ч噺鐨勬枃浠舵弿杩扮
//epoll_create 鍒涘缓epoll instance 杩斿洖鏂囦欢鎻忚堪绗� -->open creat
//鍏冲績鐨勬枃浠舵弿杩扮 閫氳繃 epoll_ctl 鏉ユ敞鍐岋紙鍒犻櫎锛� --> FD_SET FD_CLR
//epoll_wait 鐩戞祴绛夊緟鏂囦欢鎻忚堪绗﹀氨缁� ---> select
//
//epoll_create(size)
int epfd=epoll_create(50); 鍒涘缓鎻忚堪绗�
// size 鏄竴涓猦int 涓嶅鐨勬椂鍊欏唴鏍歌嚜宸辩湅鐫€鍔�
// 楠椾汉鐨勶細 鏂板唴鏍稿彲浠ワ紝灏卞唴鏍歌鍑洪敊鐨勶紒锛侊紒锛侊紒锛侊紒
//
// uname -a 3.13 鏃у唴鏍哥壒鎬т笉鏀寔hint
// 鏃у唴鏍镐笉澶燂紝澶氬啓鐐�
if(epfd<0)
{
perror("fail to epoll create");
exit(1);
}
//epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
//1. epoll鐨刦d
//2. 鎿嶄綔鐨勫畯(EPOLL_CTL_ADD(澧炲姞) EPOLL_CTL_MOD(淇敼) EPOLL_CTL_DEL(鍒犻櫎) )
//3. 瑕�(鎿嶄綔)鐨勬枃浠舵弿杩扮
//4.鏂囦欢鎻忚堪绗﹀搴旂殑鎿嶄綔缁撴瀯浣�
#if 0
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
#endif
struct epoll_event ev;
ev.events=EPOLLIN;//璇昏祫婧愮浉鍏�
ev.data.fd=0;
if(-1==epoll_ctl(epfd,EPOLL_CTL_ADD,0,&ev))
{
perror("fail to add 0");
exit(1);
}
ev.events=EPOLLIN;//璇昏祫婧愮浉鍏�
ev.data.fd=sockfd;
if(-1==epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev))
{
perror("fail to add sockfd");
exit(1);
}
struct epoll_event events[50];
while(1)
{
//epoll_wait
// 1. epfd
// 2. 杩斿洖灏辩华缁撴灉鐨勬暟缁勫悕 struct epoll_event [];
// 3. 鏁扮粍鍏冪礌鐨勪釜鏁�
// 4. 瓒呮椂淇℃伅 -1 涓嶈秴鏃�
// 杩斿洖鍊� 灏辩华鐨勬枃浠舵弿杩扮鐨勪釜鏁�
int nfds=epoll_wait(epfd,events,50,-1);
if(nfds<0)
{
perror("fail to epoll wait");
exit(1);
}
else //鏈夊氨缁� 鎸夌収椤哄簭 灏嗗氨缁粨鏋滅殑鏂囦欢鎻忚堪绗� 鏀惧叆鍒癳vents[0] ~ events[ndfs-1] 閲岄潰
{
int i;
for(i=0;i<nfds;i++)
{
if(events[i].data.fd==0)//瀵规瘡涓€涓暟缁勫厓绱犺闂� 鏄摢涓€绉嶇被鍨嬬殑io鏂囦欢鎻忚堪绗� 鎺掍粬
{
bzero(buf,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
printf("fgets:%s\n",buf);
}
else if(events[i].data.fd==sockfd)
{
confd=accept(sockfd,(SA*)&peeraddr,&len);
if(confd<0)
{
perror("fail to accept");
exit(1);
}
printf("peer ip:%s ,port:%d fd=%dis connected!\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port),confd);
ev.events=EPOLLIN;//璇昏祫婧愮浉鍏�
ev.data.fd=confd;
if(-1==epoll_ctl(epfd,EPOLL_CTL_ADD,confd,&ev))
{
perror("fail to add confd");
exit(1);
}
}
else
{
bzero(buf,sizeof(buf));
int ret_recv=recv(events[i].data.fd,buf,sizeof(buf),0);
if(ret_recv<0)
{
perror("fail to recv");
exit(1);
}
else if(ret_recv==0)
{
//鍏堝垹闄ゆ枃浠舵弿杩扮锛屽啀鍏抽棴
//epoll閲岄潰 瀛樻斁鐨勬槸鎵撳紑鐫€鐨勬枃浠舵弿杩扮
//濡傛灉鍏堝叧鍐嶅垹 浼氬嚭閿�
if(-1==epoll_ctl(epfd,EPOLL_CTL_DEL,events[i].data.fd,NULL))
{
perror("fail to del fd");
exit(1);
}
close(events[i].data.fd);
}
else
{
printf("recv:%s\n",buf);
send(events[i].data.fd,buf,strlen(buf),0);
}
}
}
}
}
return 0;
}