本地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;
		}
	}

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值