计划赶不上变化

导航

基于epoll的tcpip的服务端

#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;
}


posted on 2019-05-20 11:03  张培粉  阅读(160)  评论(0编辑  收藏  举报