理论
同一个 ip+port可以同时的被tcp模块使用也可以同时被udp模块使用。它可以同时处理来自不同运输层协议的请求。当不同的数据到达时,应用只需在不同的缓存队列中读取数据即可。
图
#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;
}
#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);
}
#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;
}