C#UDP广域网,局域网通信-原理分析
一.UDP局域网通信。
这个比较简单,关于局域网中的2台或者更多的计算机之间的UDP通信,网络上一大把,直接复制粘贴就可以使用,原理也非常简单。所以,本文不做详细介绍。
二.UDP广域通信(包括路由器穿透技术)
广域网中的通信就比局域网复杂多了,而且会出现很多情况,每种情况的处理方式不同,下面一一道来。
1. 2台直接连接广域网中的计算机的UDP通信:
这种情况是最简单的一种,因为这2台计算机直接暴露在广域网环境下,他们都拥有独立的外网IP地址。这种情况我们可以直接利用2台计算机的外网IP和端口建立UDP数据通信,和局域网非常类似。
2. 1台通过路由器上网的计算机与1台直接连接外网的计算机的UDP通信(不考虑路由器端口映射的情况):
这种情况就和上面的情况不一样了。我们将通过路由上网的计算机称作A,将直接连接外网的计算机称作S。要实现A和S的UDP相互通信,只有一个办法。就是A主动和S联系,也就是说,A先向S发送UDP数据包。一定不能反向,因为S根本不知道A的通信地址。就算是知道了,S向A发送的数据包也会被A的路由器所拦截,因为在A的路由器看来,S主动发出的UDP数据包是不请自来的,是不安全的,所以会主动摒弃掉。但是,当A主动和S联系后,A的路由器就会记录下S的地址,我们可以理解为一个通行证,这个时候S在向A发数据的时候,S已经拥有了通向A的通行证,所以,路由器会友好的将这个数据包传递到A。从而,我们就建立起了A到S的通信。同理,我们可以推出N台通过路由器上网的计算机和一台直接连接外网的计算机间的UDP通信。而这个时候,我们S就充当起了服务器的作用,用于和每台其他客户机的连接并传递数据,现在我们所用的大多数广域网的通信软件,都是采用服务器转发的机制来实现计算机间的通信。
3. 2台都通过路由器上网的计算机之间的UDP通信:
这种情况就变得非常复杂了,如果要实现2台通过路由器上网的计算机间的UDP通信,我们必须要在他们直接搭建一个桥梁,这个桥梁就是直接连接外网的S(服务器)。虽然这种方式不推荐,但是抱着研究学习的态度,我还是研究了下。可能在现实的项目中根本用不到这种方式,因为我们完全可以通过服务器转发的方式来完成所有计算机(不管是内网还是外网)的相互通信。
下面开始本篇文章的重点,2台内网计算机(通过路由器等设备上网的计算机)的UDP穿透。首先,我们把这2台计算机称为C和D。如果C或者D直接向对方发送UDP数据包,即便是他们已经知道对方通过路由器转换后的外网IP和端口,他们也不会收到来自对方的任何数据包,原因在第二种情况中已经说明,他们的路由器都会认为对方的数据包是不请自来的,不安全,都会一一摒弃掉。这个时间,我们就需要服务器S了,他要在他们两者中充当介绍人的身份。
通过第二种方式,我们已经知道了内网计算机怎样和外网计算机之间建立UDP通信,所以,我们的C和D都可以分别和S建立UDP通信,他们与S的通道是可以一一打通的。这个时候,我们的S端,已经有了C和D通过路由器转换后的外网通信IP和端口,并且保存下来,在接下来的步骤中有重要作用。这个时候,①C向S发出请求,告知C想和D通信并且请求D的外网IP和端口。②S端口收到C的请求后,向C发送有关D外网地址的数据包。③C收到有关D的通信地址数据包后,非常重要的一步来了,C马上向D的通信地址发出一个UDP数据包,可以是任何内容,因为这个数据包D根本不会收到。但之所以要这样做的原因是让C的路由器记录下D的通信地址,也就是说,让D在C的路由器处获得通往C的通行证。④这个时候,C马上向S发送数据包,让S告诉D,C已经允许D通过了,⑤并且向D发送C的外网IP和端口。⑥当D收到S发出的这个数据包后,D马上向获取的C的地址发送一个UDP请求包,这个时候,C是会收到的。当D向C发出数据包后,D的路由器也记录下了C的通信地址,所以,C也有了向D发送数据的通行证。当C接收到D的数据包后,C再向D回一个UDP应答包,这个时候,他们2者的UDP通信已经建立了,我们也就大功告成了。下面是整个通信的流程图:

C#UDP广域网,局域网通信-原理分析的更多相关文章
- UDP广域网,局域网通信-原理分析,穿透技术
一.UDP局域网通信. 这个比较简单,关于局域网中的2台或者更多的计算机之间的UDP通信,网络上一大把,直接复制粘贴就可以使用,原理也非常简单.所以,本文不做详细介绍. 二.UDP广域通信(包括路由器 ...
- 27.Socket,TCP,UDP,HTTP基本通信原理
Socket,TCP,UDP,HTTP基本通信原理(摘自百度): TCP.UDP,HTTP 底层通信都是通过 socket 套接字实现 网络上不同的计算机,也可以通信,那么就得使用网络套接字(sock ...
- 基于web的IM软件通信原理分析
关于IM(InstantMessaging)即时通信类软件(如微信,QQ),大多数都是桌面应用程序或者native应用较为流行,而网上关于原生IM或桌面IM软件类的通信原理介绍也较多,此处不再赘述.而 ...
- adb通信原理分析
关于这个问题,自己研究了一下,没有研究出来 在网络上搜罗了一下,基本上关于ADB的原理用了两张图表示: 我表示没有看懂这两个图, 又开始查阅一些一些资料: 首先知道adb的通信有Sock ...
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
自问自答的两个问题 在我们去讨论Handler,Looper,MessageQueue的关系之前,我们需要先问两个问题: 1.这一套东西搞出来是为了解决什么问题呢? 2.如果让我们来解决这个问题该怎么 ...
- UDP局域网通信的Java实现及Android平台尝试
局域网通信已经很少被他人所提及了,我曾经还尝试过通过蓝牙构建通信网络,这次有机会尝试UDP局域网通信,在这里把一些基本过程和在Android平台上的问题记录一下. 1. UDP基础知识 1.1 什么是 ...
- Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)
转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...
- Android基于UDP的局域网聊天通信
代码地址如下:http://www.demodashi.com/demo/12057.html 记得把这几点描述好咯:代码实现过程 + 项目文件结构截图 + 演示效果 1. 开发环境 1.1 开发工具 ...
- Java网络编程UDP通信原理
前言 继续今天我们的Java网络编程--TCP和UDP通信 一.TCP和UDP概述 传输层通常以TCP和UDP协议来控制端点与端点的通信 TCP UDP 协议名称 传输控制协议 用户数据包协议 是 ...
随机推荐
- Character
Character a = new Character(); Character.isUpperCase(a) 判断给点的字符是否是大写字符 Character.isLowerCase(a) 判断给定 ...
- js中的数组方法
数组的方法有数组原型方法,也有从object对象继承来的方法,这里我们只介绍数组的原型方法,数组原型方法主要有以下这些: join()push()和pop()shift() 和 unshift()so ...
- C#线程同步(1)- 临界区&Lock
文章原始出处 http://xxinside.blogbus.com/logs/46441956.html 预备知识:线程的相关概念和知识,有多线程编码的初步经验. 一个机会,索性把线程同步的问题在C ...
- Missing artifact com.oracle:ojdbc14:jar:10.2.0.3.0
1.Missing artifact com.oracle:ojdbc14:jar:10.2.0.3.0操作如下: 2.下载链接:链接:https://pan.baidu.com/s/1Ziyg2jl ...
- 不错的anroid源码在线浏览网站【学习笔记】
不错的anroid源码在线浏览网站:http://androidxref.com/
- C#中的反射解析及使用(转)
原文:https://cloud.tencent.com/developer/article/1129356 1.对C#反射机制的理解 2.概念理解后,必须找到方法去完成,给出管理的主要语法 3.最终 ...
- Springboot的异常处理与自定义异常
园友们好,元旦很快就到来了,提前祝各位园友们元旦快乐,今天给大家分享一个工作中必用一个知识点,就是使用枚举构建自定义异常并应用于springboot的异常处理器.开始之前我先把这个案例的结构大致说明一 ...
- 基于配置文件的Spring注入
基于配置文件的Spring注入 1.依赖注入的概述 依赖注入指的是通过Spring配置文件的方式创建对象时,直接通过配置的方式将数据注入到该对象的标量类型属性,并从Spring容器中获取指定对象注入到 ...
- IDEA Maven项目的Mybatis逆向工程
IDEA Maven项目的Mybatis逆向工程 1.配置.pom 如果是在多模块开发下,该文件逆向工程要生成的那个模块下的pom文件. <build> <plugins> & ...
- Qt中隐藏滚动条重新实现鼠标滚轮事件wheelEvent
delta()已经被弃用了,QT5中用的是angleDelta(),计算的时候取angleDelta().y()值. #重载方法wheelEvent(self,event),即滚轮事件方法 #---- ...