#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <pthread.h> #define MAX_EVENT_NUMBER 1024
#define TCP_BUFFER_SIZE 512
#define UDP_BUFFER_SIZE 1024 int setnonblocking( int fd )
{
int old_option = fcntl( fd, F_GETFL );
int new_option = old_option | O_NONBLOCK;
fcntl( fd, F_SETFL, new_option );
return old_option;
} void addfd( int epollfd, int fd )
{
epoll_event event;
event.data.fd = fd;
//event.events = EPOLLIN | EPOLLET;
event.events = EPOLLIN;
epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event );
setnonblocking( fd );
} int main( int argc, char* argv[] )
{
if( argc <= 2 )
{
printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );
return 1;
}
const char* ip = argv[1];
int port = atoi( argv[2] ); int ret = 0;
struct sockaddr_in address;
bzero( &address, sizeof( address ) );
address.sin_family = AF_INET;
inet_pton( AF_INET, ip, &address.sin_addr );
address.sin_port = htons( port ); int listenfd = socket( PF_INET, SOCK_STREAM, 0 );
assert( listenfd >= 0 ); ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) );//TCP连接文件描写叙述符listenfd和address绑定了
assert( ret != -1 ); ret = listen( listenfd, 5 );
assert( ret != -1 ); bzero( &address, sizeof( address ) );//清空了address
address.sin_family = AF_INET;//又一次设置address为udpserver端地址信息
inet_pton( AF_INET, ip, &address.sin_addr );
address.sin_port = htons( port );
int udpfd = socket( PF_INET, SOCK_DGRAM, 0 );
assert( udpfd >= 0 ); ret = bind( udpfd, ( struct sockaddr* )&address, sizeof( address ) );//UDP连接文件描写叙述符udpfd和address绑定了
assert( ret != -1 );
//同一个端口上绑定了两个不同类型(TCP和UDP)的socket文件描写叙述符
//创建epoll事件监听模型
epoll_event events[ MAX_EVENT_NUMBER ];
int epollfd = epoll_create( 5 );
assert( epollfd != -1 );
addfd( epollfd, listenfd );//listenfd和udpfd均注冊到内核注冊表epollfd上
addfd( epollfd, udpfd ); while( 1 )
{
int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
if ( number < 0 )
{
printf( "epoll failure\n" );
break;
} for ( int i = 0; i < number; i++ )
{
int sockfd = events[i].data.fd;
if ( sockfd == listenfd )
{
struct sockaddr_in client_address;
socklen_t client_addrlength = sizeof( client_address );
int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength );
addfd( epollfd, connfd );
}
else if ( sockfd == udpfd )
{
char buf[ UDP_BUFFER_SIZE ];
memset( buf, '\0', UDP_BUFFER_SIZE );
struct sockaddr_in client_address;
socklen_t client_addrlength = sizeof( client_address ); ret = recvfrom( udpfd, buf, UDP_BUFFER_SIZE-1, 0, ( struct sockaddr* )&client_address, &client_addrlength );
if( ret > 0 )
{
sendto( udpfd, buf, UDP_BUFFER_SIZE-1, 0, ( struct sockaddr* )&client_address, client_addrlength );
}
}
else if ( events[i].events & EPOLLIN )
{
char buf[ TCP_BUFFER_SIZE ];
while( 1 )
{
memset( buf, '\0', TCP_BUFFER_SIZE );
ret = recv( sockfd, buf, TCP_BUFFER_SIZE-1, 0 );
if( ret < 0 )
{
if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) )
{
break;
}
close( sockfd );
break;
}
else if( ret == 0 )
{
close( sockfd );
}
else
{
send( sockfd, buf, ret, 0 );
}
}
}
else
{
printf( "something else happened \n" );
}
}
} close( listenfd );
return 0;
}

第九章 TCP和UDP同一时候用复用一个port实现一个回射server的更多相关文章

  1. 图解 TCP/IP 第六章 TCP与UDP 笔记6.1 传输层的作用

     图解 TCP/IP  第六章 TCP与UDP   笔记6.1 传输层的作用   传输层必须指出这个具体的程序,为了实现这一功能,使用端口号这样一种识别码.根据端口号,就可以识别在传输层上一层的应用程 ...

  2. 第七章 TCP和UDP原理

    一.引入 1.TCP/IP协议族的传输层协议主要包括TCP和UDP 2.TCP是面向连接的可靠的传输层协议.它支持在并不可靠的网络上实现面向连接的可靠的数据传输 3.UDP是无连接的传输协议,主要用于 ...

  3. 计算机网络基础:TCP和UDP

    UDP(用户数据报协议) 应用场景:一个数据包就能完成数据通信:不需要建立会话和流量控制:多播.广播:是一种不可靠传输.(例如QQ聊天,屏幕广播) UDP协议特点: UDP是无连接的,即发送数据之前不 ...

  4. 第五章 运输层(UDP和TCP三次握手,四次挥手分析)

    序言   通过这章,可以知道其实三次握手和四次挥手其实真的好简单,通过这章的学习,我相信你也会同样的认为,以后在也不需要听到别人问三次握手的过程而自己一脸懵逼了,觉得人家好屌,其实也就是他懂你不懂,仅 ...

  5. 《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(1)-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  6. 《TCP/IP详解卷1:协议》第17、18章 TCP:传输控制协议(2)-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  7. 《TCP/IP详解卷1:协议》第19章 TCP的交互数据流-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  8. UNIX网络编程---传输层:TCP、UDP、SCTP(二)

    UNIX网络编程----传输层:TCP.UDP.SCTP 一.概述 本章的焦点是传输层:包括TCP.UDP.和SCTP(流控制传输协议).SCTP是一个较新的协议,最初设计用于跨因特网传输电话信令. ...

  9. 【RL-TCPnet网络教程】第17章 RL-TCPnet之UDP通信

    第17章      RL-TCPnet之UDP通信 本章节为大家讲解RL-TCPnet的UDP通信实现,学习本章节前,务必要优先学习第16章UDP用户数据报协议基础知识.有了这些基础知识之后,再搞本章 ...

随机推荐

  1. Python 绘图与可视化 matplotlib 填充fill和fill_between

    参考链接:https://blog.csdn.net/You_are_my_dream/article/details/53457960 fill()填充函数曲线与坐标轴之间的区域: x = np.l ...

  2. maven 测试写入JRE参数

    项目在测试时碰到一个问题,就是JVM加载参数的问题. web项目本身在注入配置信息的时候,读取的是本地的配置文件,但是配置文件的位置是卸载tomcat 里面配置的JAVA_OPTS里面的. 问题出现了 ...

  3. css所有属性(table,行列组)总结

    概述: CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: CSS声明总是以分号(;)结束,声明组以大括号({})括起来: 一.注释: CSS注释以 "/*" 开始, ...

  4. tp框架引入第三方sdk的经验总结

    tp框架开发常用到第三方的接口,这时候需要引入第三方的sdk.例如:微信扫码支付sdk,阿里大于的淘宝sdk等等 首先到官网上下载对应php的sdk文件,通常会有至少一个实例代码. 1 新建一个控制器 ...

  5. Mysql学习总结(34)——Mysql 彻底解决中文乱码的问题

    mysql 中常常出现对中文支持不友好的情况 常见的错误 "Illegal mix of collations for operation" 下面我们规整一下 mysql 数据库中 ...

  6. JAVA深克隆与浅克隆1

    复制就是得到一个副本 克隆就是复制一个对象的复本.但一个对象中可能有基本数据类型,如:int,long,float    等,也同时含有非基本数据类型如(数组,集合等)被克隆得到的对象基本类型的值修改 ...

  7. c3p0在spring中的配置

    在大家的开发和学习其中应该经经常使用到数据库的连接和使用,只是连接 的方式就有非常多种方式了,例如说用最最简单的JDBC 也好,还实用比 较复杂一点的就是数据库连接池.当然还有使用DBCP的连接的,各 ...

  8. dll开发

    _declspec(dllexport) void fun() { }

  9. Servlet学习(八)——Session

    1.Session技术 Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间.所以说Ses ...

  10. select标签下option标签里value属性有什么用以及和text的区别

    转自:http://blog.csdn.net/summer_sy/article/details/54572398 1:value的用处 <select > <option val ...