本地socket实现进程间通信-代码


 static int start(int port,char *ip)
 {
	 assert(ip);
	 int sock=socket(AF_INET,SOCK_STREAM,0);
	 if(sock<0)
	 {
		 perror("socket");
		 exit(1);
	 }
 
	 struct sockaddr_in local;
	 local.sin_port=htons(port);
	 local.sin_family=AF_INET;
	 local.sin_addr.s_addr=inet_addr(ip);
 
	 int opt=1;  //设置为接口复用
	 setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
 
	 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
	 {
		 perror("bind");
		 exit(2);
	 }
 
	 if(listen(sock,_BACKLOG_)<0)
	 {
		 perror("listen");
		 exit(3);
	 }
	 return sock;
 }

 static int epoll_server(int listen_sock)
 {
	 int epoll_fd=epoll_create(256);//生成一个专用的epoll文件描述符
	 if(epoll_fd<0)
	 {
		 perror("epoll_create");
		 exit(1);
	 }

	struct epoll_event ev;//用于注册事件
	struct epoll_event ret_ev[_MAX_];//数组用于回传要处理的事件
	int ret_num=_MAX_;
	int read_num=-1;
	ev.events=EPOLLIN;
	ev.data.fd=listen_sock;
	if(epoll_ctl(epoll_fd,EPOLL_CTL_ADD,listen_sock,&ev)<0)//用于控制某个文件描述符上的事件(注册,修改,删除)
	{
		perror("epoll_ctl");
		return -2;
	}

	int done=0;
	int i=0;
	int timeout=5000;
	struct sockaddr_in client;
	socklen_t len=sizeof(client);
	while(!done)
	{
		switch(read_num=epoll_wait(epoll_fd,ret_ev,ret_num,timeout))//用于轮寻I/O事件的发生
		{
			case0:																		  
				printf("time out\n");
				break;
			case -1:
				perror("epoll");
				exit(2);
			default:
				{
					for(i=0;i<read_num;++i)
					{
						if(ret_ev[i].data.fd==listen_sock&&(ret_ev[i].events&EPOLLIN))
						{

							int fd=ret_ev[i].data.fd;
							int new_sock=accept(fd,(struct sockaddr*)&client,&len);
							if(new_sock<0)
							{
								perror("accept");
								continue;
							}

							ev.events=EPOLLIN;
							ev.data.fd=new_sock;
							epoll_ctl(epoll_fd,EPOLL_CTL_ADD,new_sock,&ev);
							printf("get a new client...\n");
						}
						else  //normal sock
						{
							if(ret_ev[i].events&EPOLLIN)
							{
								int fd=ret_ev[i].data.fd;
								data_buf_p mem=(data_buf_p)malloc(sizeof(data_buf_t));
								if(!mem)
				perror("malloc");																	   
									continue;
								}
								mem->fd=fd;
								memset(mem->buf,'\0',sizeof(mem->buf));
								ssize_t _s=read(mem->fd,mem->buf,sizeof(mem -> buf)-1);
								if(_s>0)
								{
									mem->buf[_s-1]='\0';
									printf("client: %s\n",mem->buf);
									ev.events=EPOLLOUT;
									ev.data.ptr=mem;
									epoll_ctl(epoll_fd,EPOLL_CTL_MOD,fd,&ev);
								}
								else if(_s==0)
								{
									printf("client close...\n");
									epoll_ctl(epoll_fd,EPOLL_CTL_DEL,fd,NULL);
									close(fd);
									free(mem);
								}
								else
								{
									continue;
								}
							}
							else if(ret_ev[i].events&EPOLLOUT)	//写事件准备就绪
							{
									data_buf_p mem=(data_buf_p)ret_ev[i].data.ptr;
									int fd=mem->fd;
									char *buf=mem->buf;
									write(fd,buf,strlen(buf));
									ev.events=EPOLLIN;	  //写完,下次关心读事件
									ev.data.fd=fd;
									epoll_ctl(epoll_fd,EPOLL_CTL_MOD,fd,&ev);
							}
							else{
								//....
							}
						}
					}
				}
				break;
		}
	}

}


版权声明:本文为paopaolele原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。