网游中的网络编程3:在UDP上建立虚拟连接
目录
- 网游中的网络编程系列1:UDP vs. TCP
- 网游中的网络编程2:发送和接收数据包
- 网游中的网络编程3:在UDP上建立虚拟连接
- TODO
二、在UDP上建立虚拟连接
介绍
UDP是无连接的,一个UDPsocket可以被用做,与任意数量的计算机交换数据包。然而,在多人游戏中,我们只希望在一小部分建立起连接的计算中,交换数据包。
所以,我们需要做的第一步就是:在UDP上让两台计算机,建立起虚拟连接。
但是,首先,我们先深入到底层,弄清楚互联网是如何工作的。
互联网不是一系列的电话线
在2006年, Senator Ted Stevens做了一个互联网历史上,著名的一次演讲:
“The internet is not something that you just dump something on. It’s not a big truck. It’s a series of tubes”
当我第一次使用互联网的是:1995年,我在大学的计算机实验室中,我用Netscape浏览器上网,当时漫无目的的瞎逛。
我当时想:每次连上一个网站,就产生一些“真实的连接”,就像电话线。我十分惊奇,当我每次访问一个新的网站的时候需要花费多少钱?(作者当时认为,每次访问网站都是建立在一条通信线路之上,就像电话线,需要拉线)不会有人找上门,让我付这些线路的费用吧?
当然,这个想法现在看起来很傻。
没有直接的连接
互联中:没有一条通信电缆,直接通信的两台计算机。数据是由IP协议,通过数据包,从一个个电脑传递过来的。(就像传纸条)
一个数据包可能通过几个计算机才能到达目的地。你不能知道准确的传递过程(第一步,第二步。。。),这个过程是会变化的,是根据网络质量决定数据包的下一步走向。你可能发送过两个数据包A和B到同一个地址,它们可能走的是不同的路线。这个也是数据包无序的一个原因。
在Linux和Unix系统上(win可以用‘tracert’),可以使用‘traceroute’指令来查看数据包的传递线路和途径的主机名和IP地址。traceroute请参考
试一下traceroute指令:
traceroute: Warning: baidu.com has multiple addresses; using 220.181.57.217
traceroute to baidu.com (220.181.57.217), 64 hops max, 52 byte packets
1 192.168.1.1 (192.168.1.1) 4.727 ms 4.960 ms 4.144 ms
2 223.20.160.1 (223.20.160.1) 13.405 ms 6.047 ms 8.561 ms
3 218.241.252.185 (218.241.252.185) 4.735 ms 2.130 ms 7.771 ms
4 218.241.252.197 (218.241.252.197) 6.849 ms 5.335 ms 4.555 ms
5 202.99.1.217 (202.99.1.217) 4.025 ms 13.324 ms 3.761 ms
6 * 218.241.244.21 (218.241.244.21) 8.492 ms
218.241.244.9 (218.241.244.9) 5.389 ms
7 218.241.244.33 (218.241.244.33) 6.699 ms 4.851 ms 5.386 ms
8 * * *
注意:第八行是因为有ICMP防火墙,请求被拒绝了,所以没有探测出目的ip地址。
这个过程就能诠释:没有直接的连接。
如何收到数据包
正如第一篇文章,举的那个简单的例子:收到数据包,就像在一个房间,人们手递手传纸条。
互联网是网络的网络(网络的集合)。当然我们不仅在一个小房子中传递信件,我们能把它传到世界各地。
最好的例子是邮局系统!
当你想要发一封信给别人,你需要把你的信放到邮箱中,同时你会相信会到达收件人的手上。信件怎么到的,你不需要关心,反正到了。总得有人把你的信送到目的地,那么到底是怎么送到的呢?
首先,邮递员不会拿着你的信,直接送到目的地!邮递员拿着你的信,送到当地邮局,让邮局处理。
如果这封信是本地的,本地的邮局会收过来,安排让另外一个邮递员直接送到目的地。但是,如果信的地址不是本地的,那么本地的邮局不会直接把信送到目的地,所以邮局会送到上一级(镇邮局送到市邮局),或者送到临近城市的邮局,如果目的地太远就会送到飞机场。信件的传输方式是用大卡车。
我们来看一个例子:假定一封信,从洛杉矶寄到北京,本地邮局接收到信,然后发现是国际信件,就直接送到洛杉矶的邮件中心。这封信,确认收件的地址无误,就安排到下一班飞机飞往北京的航班。
飞机着陆在北京,北京的邮件系统肯定是和洛杉矶的邮件系统不一样。北京的邮件中心收到这封信后,就送到具体的区级的当地邮局,最终,这封信会通过一个邮递员直接送到收件人的手里。
就像邮局系统,通过地址传递信件一样。网络传递数据包是通过IP地址。传递数据包的细节和路径选择是非常复杂的,但是基本思想:每个路由器都是一台计算机,由路由表决定数据下一步走的地址。(这部分我省略了一些路由和路由表的部分,我没有看懂,后面研究明白,回来再补全。现在不影响后面的阅读)
编辑路由表的工作是网络管理员的工作,不是我们这些程序员关心的问题(还好
网游中的网络编程3:在UDP上建立虚拟连接的更多相关文章
- 网游中的网络编程系列1:UDP vs. TCP
原文:UDP vs. TCP,作者是Glenn Fiedler,专注于游戏网络编程相关工作多年. 目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网 ...
- Socket网络编程TCP、UDP演示样例
Socket网络编程: 1) OSI(了解): 国际标准化组织ISO(International Orgnization for Standardization)指定了网络通信的模型:开放系统互联(O ...
- 第84节:Java中的网络编程(中)
第84节:Java中的网络编程(中) 实现客户端和服务端的通信: 客户端需要的操作,创建socket,明确地址和端口,进行键盘录入,获取需要的数据,然后将录入的数据发送给服务端,为socket输出流, ...
- 第78节:Java中的网络编程(上)
第78节:Java中的网络编程(上) 前言 网络编程涉及ip,端口,协议,tcp和udp的了解,和对socket通信的网络细节. 网络编程 OSI开放系统互连 网络编程指IO加网络 TCP/IP模型: ...
- 第62节:探索Java中的网络编程技术
前言 感谢! 承蒙关照~ 探索Java中的网络编程技术 网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考. 一座塔有七层,我们需要闯关. 第一层物理层 ...
- 网络编程第三讲UDP编写
网络编程第三讲UDP编写 一丶UDP简介 UDP是面向无连接的.就是说数据传输会丢掉.网络延时比较大的情况下.会早上丢包.例如视频通话.就是UDP UDP不需要建立建立. 下面有UDP编写流程图 下图 ...
- C#网络编程入门之UDP
目录: C#网络编程入门系列包括三篇文章: (一)C#网络编程入门之UDP (二)C#网络编程入门之TCP (三)C#网络编程入门之HTTP 一.概述 UDP和TCP是网络通讯常用的两个传输协议,C# ...
- Java中的网络编程
Java中的网路编程主要是Java的Socket编程,属于JavaEE中的高级的部分,以下内容是对java网路编程的一个小结,代码都是经过编译调试的 C/S程序应用:客户/服务器模式,如QQ客户端 ...
- JAVA中-面向网络编程---单层交互
面向网络编程---单层交互: 客户端说明: /* * 实现TCP客户端,链接到服务器 * 和服务器实现数据交互 * 实现TCP客户端的类 java.net.Scoket * 构造方法: * Socke ...
随机推荐
- C# Bitmap类型与Byte[]类型相互转化
Bitmap => byte[] Bitmap b = new Bitmap( "test.bmp "); MemoryStream ms = new Memory ...
- 携程Android App插件化和动态加载实践
携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...
- Python多线程编程之多线程加锁
Python语言本身是支持多线程的,不像PHP语言. 下面的例子是多个线程做同一批任务,任务总是有task_num个,每次线程做一个任务(print),做完后继续取任务,直到所有任务完成为止. #co ...
- DataGridView很详细的用法(转载)
一.DataGridView 取得或者修改当前单元格的内容: 当前单元格指的是 DataGridView 焦点所在的单元格,它可以通过 DataGridView 对象的 CurrentCell 属性取 ...
- 解决chi_sim.traineddata报read_params_file: parameter not found: allow_blob_division
在使用语音库时候 遇到报错:allow_blob_division,例如使用chi_sim.traineddata;在chi_sim.traineddata(注意版本)文件目录下,使用命令行执行: c ...
- int android.graphics.Bitmap.getRowBytes()
int android.graphics.Bitmap.getRowBytes() Return the number of bytes between rows in the bitmap's pi ...
- GDAL 遥感图像处理后的数据保存为图像文件的实现方法
在遥感图像处理中,GDAL库不仅能读取和处理大部分的遥感图像数据,而且还能够实现图像处理后将数据保存为图像的功能. 本文就详细介绍如何将内存中的图像数据保存为.tif格式. 首先,遥感数据处理完,保存 ...
- 将自己写的windows服务加入到windows集群中
最近发现windows集群能进行很多自定义,比如在集群中加入自己编写的服务. 能自定义的可不少,截个图: 本次演示中,只想用“通用服务”这个类型. 先列下步骤 编写一个记录时间的Windows服务,这 ...
- [转] Autofac创建实例的方法总结
1.InstancePerDependency 对每一个依赖或每一次调用创建一个新的唯一的实例.这也是默认的创建实例的方式. 官方文档解释:Configure the component so tha ...
- git常用命令-基本操作
git常用命令-基本操作 1) 新增文件 新增了Test_1.java git add Test_1.java git commit –m “新增了Test_1.java” git push ...