使用UDP完成网络通信
语言聊天有可以接受丢包但是不能接受乱序的特性,所以可以采用UDP来
传输数据提高效率。
因为UDP本身不可靠传输的特性,为了保证玩家可靠的接入服务器和一些
操作的正确执行,还是需要一些额外的代码保证UDP的可靠性传输。
一个简单的方案是在发送端发送一个包之后,等待接收端发送的recvack,
如果没有接收到recvack则重复发送直到超时。发送端接到recvack则发送
confrimack。接收端若没有收到confrimack重复发送知道超时。
为了区分可靠和非可靠性传输,为以枚举的形式封包提供了不同的包类型
需要提供不同的:
enum sendtype{
safe_send,
unsafe_send,
并且提供不同的发送接口:
void unsafe_send(char* buf,int len,const sockaddr* addr, int addrlen){
int datalen += sizeofsenddatahead;
senddata * data = (senddata*)malloc(datalen);
data->type = unsafe_send;
data->len = len;
memcpy(data->data, buf, len);
sendto(fd, data, datalan, 0, addr, addrlen);
}
void safe_send(char* buf,int len,const sockaddr* addr,int addrlen){
int datalen += sizeofsenddatahead;
senddata * data = (senddata*)malloc(datalen);
data->type = safe_send;
接收端在接收到数据后,如果是safe_send,则发送recvack:
void sendrecvack(sockaddr_in & addr, int addrlen){
recvack cmd;
cmd.isrecv = cmdrecvack;
safe_send(&cmd, sizeofconfrimack, (sockaddr*)&addr, addrlen);
发送端在接收到recvack后,发送confrimack:
void sendconfrimack(sockaddr_in & addr, int addrlen){
confrimack cmd;
cmd.isrecv = cmdconfrimack;
unsafe_send(&cmd, sizeofconfrimack, (sockaddr*)&addr, addrlen);
使用心跳控制重发包:
void safesendheadbeat(int time, void * data){
if (!vsenddata.empty()){
senddata * data = vsenddata.front();
sendto(fd, data, data->len, 0, addr, addrlen);
}
addtime(25, safesendheadbeat, data);
使用心跳控制recvack:
void recvackheadbeat(int time, void * data){
if (recvack != 0){
sendto(fd, recvack, recvack->len, 0, addr, addrlen);
}
addtime(25, recvackheadbeat, recvack);
使用UDP完成网络通信的更多相关文章
- UDP SOCKET网络通信 C#
接收端 using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Thread ...
- UDP实现网络通信程序
VC6.0创建基于UDP协议的网络聊天程序 只有一个工程UDP,服务器和客户端都是这个工程,因为UDP中C/S区分不强化 只讲关键部分,避免累赘 1.为对话框添加控件 2.为控件绑定变量和消息函数 启 ...
- 计算机网络通信、线程、tcp、udp通信及信号量等读书笔记
一.计算机网络 1.什么是计算机网络:把分布在不同地理位置的计算机与专门的网络设备用通信线路互相连成一个规模大.功能强的系统,从而使众多计算机可以方便地互相传递信息.共享软件.硬件.数据信息等.简单来 ...
- Laxcus大数据管理系统2.0(8)- 第六章 网络通信
第六章 网络通信 Laxcus大数据管理系统网络建立在TCP/IP网络之上,从2.0版本开始,同时支持IPv4和IPv6两种网络地址.网络通信是Laxcus体系里最基础和重要的一环,为了能够利用有限的 ...
- P2P通信中使用ENet提供UDP的可靠传输
ENet官网:http://enet.bespin.org/ 按照他的说法: ENet's purpose is to provide a relatively thin, simple and ro ...
- Hololens开发笔记:UDP接收数据
Hololens的应用需要与其他设备通信的时候,UDP是比较方便的一种方式,Unity3d 2017.3 C#开发的时候可以用Windows.Networking.Sockets.DatagramSo ...
- Java入门系列-25-NIO(实现非阻塞网络通信)
还记得之前介绍NIO时对比传统IO的一大特点吗?就是NIO是非阻塞式的,这篇文章带大家来看一下非阻塞的网络操作. 补充:以数组的形式使用缓冲区 package testnio; import java ...
- 使用 acl 编写 UDP 网络程序(UDP 重传及可靠性机制)
在当今网络世界,虽然大部分网络应用都是基于 TCP 的,但有时 UDP 的网络通信也有用武之处.acl 的网络库中不仅提供了基于 TCP 的网络套接字流,同时也提供了 UDP 的网络库(目前 acl ...
- .NET知识结构
.NET知识结构 .NET介绍 微软.NET战略及技术体系,.NET Framework框架类库(FCL),公共语言运行时(CLR),通用类型系统(CTS),公共语言规范(CLS),程序集(Assem ...
随机推荐
- 《JavaScript高级程序设计》里对 call() 和 apply() 的解释 (116页)
每个函数都包含两个非继承而来的方法:apply()和call().这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值. apply(): 方法接受两个参数:一个是在其 ...
- 16、Collection接口及其子接口Set和List(常用类LinkedList,ArrayList,Vector和Stack)
16.Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同 ...
- iOS UIAlertView 文字对其方式 文字大小 设置方法
- (void) willPresentAlertView:(UIAlertView *)alertView { for (UIView *subViewin alertView.subviews) ...
- 基于java:读写一个英文的txt文件,记录单词个数,并输出十个出现最多的单词及出现的个数;
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; class W ...
- nodejs服务实现反向代理,解决本地开发接口请求跨域问题
前后端分离项目需要解决第一个问题就是,前端本地开发时如何解决通过ajax请求产生的跨域的问题.一般的做法是通过本地配置nginx反向代理进行处理的,除此之外,还可以通过nodejs来进行代理接口.当然 ...
- haproxy-代码阅读-内存管理
haproxy内存池概述 内存池按照类型分类,每个类型的内存池都有一个名字,用链表记录空闲的内存块,每个内存块大小相等,并按照16字节对齐. haporxy用pool_head 结构记录内存池 str ...
- python_day5--->递归函数,二分法查找
li = [1, 5, 6, 7, 12, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333]def er(num,li): if len(li) ==0: ...
- ORACLE中死锁的知识点总结
死锁的概念 什么是死锁呢? 其实我们生活中也有很多类似死锁的例子. 我先举一个生活中的例子:过年回家,父亲买了一把水弹枪,儿子和侄子争抢着要先玩,谁也不让谁,拆开包装后,一个抢了枪, 一个逮住了子 ...
- 生成JSON数据--Gson(谷歌)方法
Gson生成JSON数据方法: 创建相应的类,然后创建对象,toJson()进去就可以了 要求:生成如下JSON数据 1.{"age":4,"name":&qu ...
- Java对于内存的需要知道的知识
内存 内存大家都知道(当然不是硬盘啊).与c.c++相比呢,Java在内存管理的方面一个优越之处就是我们不用显式的去对对象进行内存的分配和内存的回收,可能有人会着迷于对内存使用分配的这种快感,但是随着 ...