热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

epoll高级应用之同时处理tcp/udp的服务器

理论同一个ipport可以同时的被tcp模块使用也可以同时被udp模块使用。它可以同时处理来自不同运输层协议的请求。当不同的数据到达时,应用只需在不同的缓存队列中读

理论

同一个 ip+port可以同时的被tcp模块使用也可以同时被udp模块使用。它可以同时处理来自不同运输层协议的请求。当不同的数据到达时,应用只需在不同的缓存队列中读取数据即可。

这里写图片描述

/*server*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include#define EVENT_LENGTH 1024
#define TCP_BUFFER 1024
#define UDP_BUFFER 1024int setnonblock(int fd)
{int old_option=fcntl(fd,F_GETFL);int new_option=old_option|O_NONBLOCK;fcntl(fd,F_SETFL,new_option);return fd;
}
void add_event(int epoll_fd,int fd)
{struct epoll_event event;event.events=EPOLLIN|EPOLLET;event.data.fd=fd;epoll_ctl(epoll_fd,EPOLL_CTL_ADD,fd,&event);setnonblock(fd);
}
int startup(char * ip,char *port)
{int listen_sock&#61;0;if((listen_sock&#61;socket(AF_INET,SOCK_STREAM,0))<0){perror("listen");exit(1);}}struct sockaddr_in address;bzero(&address,sizeof(address));address.sin_family&#61;AF_INET;address.sin_port&#61;htons(atoi(port));int ret&#61;0;if((ret&#61;inet_pton(AF_INET,ip,&address.sin_addr))&#61;&#61;0){printf(" ip ge shi cuowu\n");exit(2);}else if(ret<0){perror("inet_pton");exit(3);}if(bind(listen_sock,(const struct sockaddr*)&address,sizeof(address))&#61;&#61;-1){perror("bind");exit(4);}if(listen(listen_sock,100)<-1){perror("listen");exit(5);}return listen_sock;
}
int udp_server(char*ip,char*port)
{int udp&#61;0;if((udp&#61;socket(AF_INET,SOCK_DGRAM,0))<0){perror("udp");exit(6);}struct sockaddr_in address;bzero(&address,sizeof(address));address.sin_family&#61;AF_INET;address.sin_port&#61;htons(atoi(port));int ret&#61;0;if((ret&#61;inet_pton(AF_INET,ip,&address.sin_addr))&#61;&#61;0){printf(" ip ge shi cuowu\n");exit(7);}else if(ret<0){perror("inet_pton");exit(8);}if(bind(udp,(const struct sockaddr*)&address,sizeof(address))&#61;&#61;-1){perror("bind");exit(9);}return udp;
}
int main(int argc,char*argv[])
{if(argc!&#61;3){printf("error input\n");exit(6);}int listen&#61;startup(argv[1],argv[2]);int udp&#61;udp_server(argv[1],argv[2]);struct epoll_event events[EVENT_LENGTH];int epoll_fd&#61;epoll_create(5);assert(epoll_fd!&#61;-1);add_event(epoll_fd,listen);add_event(epoll_fd,udp);char udp_buff[UDP_BUFFER];memset(udp_buff,0,UDP_BUFFER);char tcp_buff[TCP_BUFFER];memset(tcp_buff,0,TCP_BUFFER);while(1){int number&#61;epoll_wait(epoll_fd,events,10,-1);if(number<0)printf("epoll wait fail\n");break;}int i&#61;0;for( i&#61;0;iint sockfd&#61;events[i].data.fd;if(sockfd&#61;&#61;listen){while(1){struct sockaddr_in client;socklen_t len&#61;sizeof(client);int peer&#61;accept(sockfd,(struct sockaddr *)&client,&len);if(peer&#61;&#61;-1&&(errno&#61;&#61;EAGAIN||errno&#61;&#61;EWOULDBLOCK))break;printf("peer ip:%s \t port:%d \n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));add_event(epoll_fd,peer);bzero(&client,sizeof(client));}}else if(sockfd&#61;&#61;udp){struct sockaddr_in client_address;socklen_t len&#61;sizeof(client_address);int size&#61;recvfrom(sockfd,udp_buff,UDP_BUFFER-1,0,(struct sockaddr *)&client_address,&len);udp_buff[size]&#61;0;printf("udp client say# %s",udp_buff);fflush(stdout);printf("please enter#");fflush(stdout);size&#61;read(0,udp_buff,1024);udp_buff[size]&#61;0;sendto(sockfd,udp_buff,UDP_BUFFER-1,0,(struct sockaddr*)&client_address,len);}else if(events[i].events&EPOLLIN){printf("tcp client say#:");int size&#61;0;while(1){size&#61;recv(sockfd,tcp_buff,1024,0);if(size&#61;&#61;-1){if(errno&#61;&#61;EAGAIN||errno&#61;&#61;EWOULDBLOCK)break;close(sockfd);break;}else if(size&#61;&#61;0){close(sockfd);printf("tcp disconnect");goto pos;}tcp_buff[size]&#61;0;printf("%s",tcp_buff);fflush(stdout);}printf("please Enter#");fflush(stdout);size&#61;read(0,tcp_buff,1024);tcp_buff[size]&#61;0;send(sockfd,tcp_buff,size,0);}else {printf("something happened \n");}pos:printf("\n");}}close(listen);return 0;
}/*tcp_client*/
#include
#include
#include
#include
#include
#include
#include
int main(int argv,const char*arg[])
{int req_sock&#61;socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in sock_in;sock_in.sin_family&#61;AF_INET;sock_in.sin_port&#61; htons(atoi(arg[2]));sock_in.sin_addr.s_addr&#61;inet_addr(arg[1]);socklen_t len&#61;sizeof(sock_in);connect(req_sock,(struct sockaddr*)&sock_in,len);char buf[1024];memset(buf,0,1024);while(1){printf("please Enter:");fflush(stdout);ssize_t s&#61;read(0,buf,sizeof(buf));buf[s]&#61;0;s&#61;write(req_sock,buf,s);if(s<0){perror("write");exit(1);}s&#61;read(req_sock,buf,sizeof(buf));if(s>0){buf[s]&#61;0;if(strcmp(buf,"quit")&#61;&#61;0)break;printf("server say:%s",buf);fflush(stdout);}}return 0;close(req_sock);
}
/*udp_client*/
#include
#include
#include
#include
#include
int main(int argc,char*argv[])
{if(argc!&#61;3){printf("please enter ip port\n");exit(1);}int sock&#61;socket(AF_INET,SOCK_DGRAM,0);char buff[1024];struct sockaddr_in server;server.sin_family&#61;AF_INET;server.sin_port&#61;htons(atoi(argv[2]));server.sin_addr.s_addr&#61;inet_addr(argv[1]);socklen_t len&#61;sizeof(struct sockaddr_in);int size&#61;0;while(1){printf("please Enter #");fflush(stdout);size&#61;read(0,buff,1024);buff[size]&#61;0;sendto(sock,buff,1024,0,(struct sockaddr*)&server,len);size&#61;recvfrom(sock,buff,1024,0,(struct sockaddr*)&server,&len);buff[size]&#61;0;printf("server say#%s",buff);}return 0;
}

这里写图片描述


推荐阅读
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
author-avatar
阳光ai星星
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有