使用 acl 编写 UDP 网络程序(UDP 重传及可靠性机制)
在当今网络世界,虽然大部分网络应用都是基于 TCP 的,但有时 UDP 的网络通信也有用武之处。acl 的网络库中不仅提供了基于 TCP 的网络套接字流,同时也提供了 UDP 的网络库(目前 acl 库的网络部分仅提供了基本的 UDP 功能,如果想实现 UDP 重传及可靠性机制,大家可以参考 udt --https://sourceforge.net/projects/udt/ 库)。
使用 acl 网络库无论编写客户端还是服务器程序,都需要首先调用 acl_vstream_bind 接口绑定本机地址,该函数的定义如下:
/**
* 针对 UDP 通信,该函数用来绑定本地 UDP 地址,如果绑定成功,则创建
* ACL_VSTREAM 对象, 用户可以象调用 ACL_VSTREAM 对象的读写接口
* @param addr {const char*} 本地 UDP 地址,格式:ip:port
* @param rw_timeout {int} 读写超时时间(秒)
* @return {ACL_VSTREAM*} 返回 NULL 表示绑定失败
*/
ACL_API ACL_VSTREAM *acl_vstream_bind(const char *addr, int rw_timeout);
然后就可以调用 acl_vstream_read/acl_vstream_write 两个函数以 UDP 方式进行网络数据的读写了,因为 UDP 传输是不保证顺序及可靠性的,所以 acl 网络库中的其它读写函数就不被用在 UDP 读写操作中。
下面一个简单的 UDP 服务端程序:
static void udp_server(void)
{
const char *addr = "127.0.0.1:1088";
char buf[4096];
int ret;
ACL_VSTREAM *stream = acl_vstream_bind(addr, 0); /* 绑定 UDP 套接口 */
if (stream == NULL) {
printf("acl_vstream_bind %s error %s\r\n", addr, acl_last_serror());
return;
}
printf("bind udp addr %s ok\r\n", addr);
while (1) {
/* 等待客户端数据 */
ret = acl_vstream_read(stream, buf, sizeof(buf) - 1);
if (ret == ACL_VSTREAM_EOF) {
printf("acl_vstream_read error %s\r\n", acl_last_serror());
break;
}
/* 输出服务器绑定地址及远程客户端地址 */
printf("local addr: %s, peer addr: %s, total: %d\r\n",
ACL_VSTREAM_LOCAL(stream), ACL_VSTREAM_PEER(stream), i);
/* 回写数据至客户端 */
ret = acl_vstream_write(stream, buf, ret);
if (ret == ACL_VSTREAM_EOF) {
printf("acl_vtream_writen error %s\r\n", acl_last_serror());
break;
}
}
/* 关闭 UDP 套接字 */
acl_vstream_close(stream);
}
使用 acl 编写的 UDP 客户端示例如下:
static void udp_client(void)
{
const char *local_addr = "127.0.0.1:1089"; /* 本客户端绑定的地址 */
const char *peer_addr = "127.0.0.1:1088"; /* 服务端绑定的地址 */
int i, ret, dlen;
char buf[1024], data[1024];
ACL_VSTREAM *stream = acl_vstream_bind(local_addr, 2); /* 绑定 UDP 套接口 */
if (stream == NULL) {
printf("acl_vstream_bind %s error %s\r\n",
local_addr, acl_last_serror());
return;
}
memset(data, 'X', sizeof(data);
dlen = sizeof(data);
for (i = 0; i < 100; i++) {
/* 每次写时需要设定服务端地址 */
acl_vstream_set_peer(stream, peer_addr);
/* 向服务端写入数据包 */
ret = acl_vstream_write(stream, data, dlen);
if (ret == ACL_VSTREAM_EOF) {
printf("acl_vtream_writen error %s\r\n",
acl_last_serror());
break;
}
/* 从服务端读取数据 */
ret = acl_vstream_read(stream, buf, sizeof(buf));
if (ret == ACL_VSTREAM_EOF) {
printf("acl_vstream_read error %s\r\n",
acl_last_serror());
break;
}
}
/* 关闭客户端 UDP 套接字 */
acl_vstream_close(stream);
}
由以上两个例子可以看出,使用 acl 网络库编写 UDP 程序也是非常简单的,但有几点需要注意:
1、虽然 acl 网络库中的 UDP 功能也借用 ACL_VSTREAM 结构定义及 acl_vstream_xxx 等接口定义,但 UDP 传输依然是数据包式(即非流式),所以 acl 网络库中的有关 TCP 的使用方法在 UDP 中并不适合(如:acl_vstream_readn, acl_vstream_gets);
2、UDP 传输不保证顺序性及可靠性,所以 acl 网络库在绑定 UDP 端口时允许用户指定读超时时间;
3、使用 acl 网络库编写 UDP 客户端时,在每次向服务端写数据时,最好每次都先通过 acl_vstream_set_peer 设定服务端绑定地址。
参考:
acl 项目下载地址:https://sourceforge.net/projects/acl/
svn:svn://svn.code.sf.net/p/acl/code/trunk acl-code
github:https://github.com/zhengshuxin/acl
udp 服务端示例:acl\samples\udp_server
udp 客户端示例:acl\samples\udp_client
https://my.oschina.net/u/568966/blog/309529
使用 acl 编写 UDP 网络程序(UDP 重传及可靠性机制)的更多相关文章
- udp网络程序-发送、接收数据
1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8from socket im ...
- UDP网络程序模型设计
UDP网络程序设计 1. UDP网络编程模型程序初始化 1.1服务器使用的函数 创建socket----->socket 绑定地址-------->bind 接受数据--------> ...
- UDP网络程序,客户端和服务端交互原理
创建一个udp客户端程序的流程是简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实 ...
- UDP网络程序实例
根据前面所讲的网络编程的基础知识,以及UDP网络编程的特点,下面创建一个广播数据报程序.广播数据报是一种较新的技术,类似于电台广播,广播电台需要在指定的波段和频率上广播信息,收听者也要将收音机调到指定 ...
- UDP 网络程序-发送_接收数据
""" 创建udp连接 发送数据给 """ from socket import * # 创建udp套接字,使用SOCK_DGRAM udp ...
- Python复习笔记(六)网络编程(udp/tcp)
一.网络-udp(用户数据报协议) 用户数据报协议 类似写信,不安全,数据有可能丢 1.1 ip地址 注意: IP地址127.0.0.1 ~ 127.255.255.255 用于回路测试 私有ip地址 ...
- Java之网络编程UDP和TCP
注*部分转来的 第1章 网络通信协议 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样.在计算机网 ...
- 网络编程——UDP协议和通信
第1章 UDP与TCP协议 在介绍TCP/IP结构时,提到传输层的两个重要的高级协议,分别是UDP和TCP,其中UDP是User Datagram Protocol的简称,称为用户数据报协议,TCP是 ...
- python网络编程-udp
目录 1. 创建socket 2. udp网络程序-发送数据 3. udp网络程序-接收数据 4. python3中的编码转换 5. udp端口绑定 1. 创建socket 在 Python 中 使用 ...
随机推荐
- 项目启动部署时报错:java.lang.NoSuchMethodError
报错: ================================================================================================ ...
- 经典卷积神经网络的学习(三)—— Inception Net
Google Inception Net 首次出现在 ILSVRC 2014 的比赛中(和 VGGNet 同年),就以较大优势拔得头筹.那届比赛中的 Inception Net 一般被称为 Incep ...
- 数据库版本管理工具Flyway——基础篇
Flyway 默认规约 SQL 脚本文件默认位置是项目的源文件夹下的db/migration 目录. Java 代码默认位于db.migration 包. SQL 脚本文件及Java 代码类名必须遵循 ...
- 我是如何进行code review的
众所周知,代码审查是软件开发过程中十分重要的环节,楼主结合自己的实际工作经验,和大家分享一下在实际工作中代码审查是如何开展的, 笔者水平有限,若有错误和纰漏,还请大家指正. 代码审查的阻力 我想不通公 ...
- Function函数
一般大家都用这个写法来定义一个函数: function Name([parameters]){ functionBody }; //alert(typeof Name) // Function 当我们 ...
- template.js小小说明
教程 template.js 一款 JavaScript 模板引擎,简单,好用.提供一套模板语法,用户可以写一个模板区块,每次根据传入的数据,生成对应数据产生的HTML片段,渲染不同的效果. 简介 主 ...
- PHP数组教程
定义数组 PHP数组array是一组有序的变量,其中每个变量被叫做一个元素. 一.定义数组 可以用 array() 语言结构来新建一个数组.它接受一定数量用逗号分隔的 key => value ...
- 正态分布(normal distribution)与偏态分布(skewed distribution)
存在正太分布的概念,自然也少不了偏态分布. 正态分布(normal distribution) 偏态分布(skewed distribution) 左偏态:left skewed distributi ...
- 信号、系统与滤波器设计(matlab)
0. 基本概念 AWG:Additive White(zero-mean) Gaussian,可加白噪声: AWGN:Additive White(zero-mean) Gaussian Noise ...
- symfony中doctrine常用属性
转 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html 1. d ...