【网络】UDP服务器的实现
来源:互联网 发布:笔记本音效增强软件 编辑:程序博客网 时间:2024/06/06 04:38
UDP服务器实现的基本步骤
(1)利用socket函数创建套接字
(2)服务器用bind进行IP和端口号的绑定
(3)不需要设置监听状态
(4)绑定后直接读写
相关函数
recvfrom
作用
用来数据的接收
头文件
#include<sys/types.h>
#include<sys/socket.h>
函数原型
int recvfrom(int sockfd, void* buf, ssize_t len, int flags, struct sockaddr* src_addr,socklen_t *addrlen);
参数
sockfd表示当前的套接字
buf表示要接收的数据指针
len表示接收的长度
flags参数设置为0
src_addr表示发送方的协议地址
addrlen表示src_addr的大小
返回值
成功返回0
错误返回-1
sendto
作用
用来进行数据的发送
头文件
#include<sys/types.h>
#include<sys/socket.h>
函数原型
int sendto(int sockfd, void* buf , ssize_t len, int flags, struct sockaddr * src_addr, socklen_t addrlen);
参数
sockfd表示当前的套接字
buf表示要发送的数据指针
len表示要发送的数据长度
flags设置为0
src_addr为发送方的协议地址
addrlen为src_addr的大小
返回值
成功返回0错误返回-1
代码实现
server.c
#include<stdio.h>#include<stdlib.h>#include<error.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h>static void Usage(){printf("Usage: [ipaddr] [port]\n");exit(1);}int main(int argc, char* argv[]){if(argc != 3){Usage();}//创建socketint sockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd < 0){perror("socket");exit(4);}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(atoi(argv[2]));addr.sin_addr.s_addr = inet_addr(argv[1]);//进行绑定if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr)) < 0){perror("bind");exit(2);}char buf[1024];//收发数据while(1){struct sockaddr_in client;socklen_t clientLen = sizeof(client);ssize_t s = recvfrom(sockfd, buf ,sizeof(buf)-1,0,(struct sockaddr*)&client,&clientLen);if(s < 0){perror("recvfrom");exit(3);}else if(s == 0){continue;}else {buf[s] = 0;printf("IP: %s , Port : %d : %s\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf);sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client,clientLen);}}close(sockfd);return 0;}
client.c
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<error.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>static Usage(){printf("Usage: [ipaddr] [port]\n");exit(1);}int main(int argc,char* argv[]){if(argc != 3){Usage();}//创建socketint sockfd = socket(AF_INET,SOCK_DGRAM,0);if(sockfd < 0){perror("sockfd");exit(2);}printf("请输入...\n");char buf[1024];//进行写和读while(1){printf("#client : ");fflush(stdout);ssize_t s = read(0,buf,sizeof(buf)-1);if(s < 0){perror("read");exit(3);}buf[s-1] = '\0';//进行发送struct sockaddr_in client;client.sin_family = AF_INET;client.sin_port = htons(atoi(argv[2]));client.sin_addr.s_addr = inet_addr(argv[1]);s = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client,sizeof(client));if(s < 0){perror("sendto");exit(4);}struct sockaddr_in server;socklen_t len = sizeof(server);s = recvfrom(sockfd,buf,sizeof(buf)-1,0,(struct sockaddr*)&server,&len);if(s < 0){perror("recvfrom");exit(5);}//正常收到buf[s] = 0;printf("IP : %s , Port : %d : %s\n",inet_ntoa(server.sin_addr),ntohs(server.sin_port),buf);}close(sockfd);return 0;}
运行结果
客户端发送消息
服务器接受消息
如何保证UDP的可靠性
传输层无法保证数据的可靠传输,只能通过应用层来实现了。
实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
实现确认机制、重传机制、窗口确认机制。
除了利用Linux协议栈以及上层socket机制之外,自己可以通过抓包和发包的方式去实现可靠性传输
需要实现如下功能:
发送:包的分片、包确认、包的重发
接收:包的调序、包的序号确认
目前有如下开源程序利用udp实现了可靠的数据传输
分别为RUDP、RTP、UDT。
方法1:RUDP
RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。
在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。
方法2:RTP
实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;
这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用
如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。
RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。
RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。
RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。
方法3:UDT
基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。
UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。
顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。
UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。
由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
- 【网络】UDP服务器的实现
- UNIX网络编程--实现并发UDP服务器
- 【网络】实现简单的TCP、UDP服务器、TCP多进程/多线程服务器
- UDP-网络服务器模型
- <网络编程培训之三> 实现TCP/UDP的简单Echo服务器
- 单用户UDP服务器的简单实现
- UDP服务器、客户端的简单实现
- UDP: 用Socket 实现UDP 协议下的网络通信
- UDP下的网络穿越代码实现
- UDP实现网络数据传输
- 网络编程之UDP服务器
- UDP网络编程服务器部分
- Python网络编程02----基于UDP的Python简易服务器
- Linux网络编程[UDP客户端服务器的编程模型]
- 【Linux网络编程】基于UDP的客户端/服务器程序
- 【网络】TCP服务器的实现
- 【网络】Select服务器的实现
- C#的UDP服务器
- hdu4725The Shortest Path in Nya Graph(拆点 + 最短路dijkstra)
- PHP开发微信自定义菜单40033不转义中文的方法
- zoj1276Optimal Array Multiplication Sequence 动态规划
- Laravel5.3初步使用二(整体步骤、路由配置、Model层配置)
- imx6dl 关闭屏幕休眠
- 【网络】UDP服务器的实现
- STM32——USB详细使用说明 附件HID的双向通信
- 【Spring】
- 物料价值差异过账科目示例(PRD)
- c++输出数组方式
- Hibernate映射——多对一单向关联映射(四)
- hdu 1243 反恐训练营 LCS变形
- Python 2 和 3 区别
- 《SSM框架实战》 整合 Freemarker