文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

1.背景

在上一篇博客中我详细介绍了809协议的内容。809协议规范了通信的报文,通信的规则等,但是并没限制通信使用的传输协议。这里,我将分别介绍利用TCP和UDP传输协议来实现的809协议对接的方法。

2.TCP和UDP的介绍

TCP协议和UDP协议均是面向传输层的一种协议。而我们常说的HTTP协议则是面向应用层的一种协议。

我们常说的TCP/IP协议,则是一个协议簇,其中TCP、UDP协议均包含于这个协议簇。至于这个协议为什么叫TCP/IP,是因为TCP和IP协议是其中最重要的两个协议。

2.1TCP协议介绍

TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,只简单的描述下这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

总结上面这段话,主要包含了两个关键词:三次握手、可靠连接:

  

如建立连接一般复杂,TCP协议断开也相对复杂,需要进行四次挥手:

           

2.2UDP协议介绍

UDP(User Data Protocol),即用户数据报协议,其包含的特征主要如下:

a.UDP是一个非连接的协议,传输数据之前,源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

b.由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

c.UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

d.吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

e.UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

f.UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

总结UDP协议,其最大的特点是其无连接性,支持广播通信(支持一对多、多对多通信)。广播地址(Broadcast Address)是专门用于同时向网络中所有工作站进行发送的一个地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。例如,对于10.1.1.0 (255.255.255.0 )网段,其广播地址为10.1.1.255 (255 即为2 进制的11111111 ),当发出一个目的地址为10.1.1.255 的分组(封包)时,它将被分发给该网段上的所有计算机。

2.3协议对比

TCP与UDP区别总结:

 a.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接。

 b.TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 。

 c.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的

UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)。

d.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信 。

e.TCP首部开销20字节;UDP的首部开销小,只有8个字节。

f.TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。

3.Socket编程

3.1基本概念

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

目前各大主流语言基本都支持socket编程。C#基于socket封装了TCPClient以及UDPClient类,使得socket编程更加简单。

在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:

同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。也就是必须一件一件事做,等前一件做完了才能做下一件事。例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事。

异步:异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。 例如 ajax请求(异步): 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕。

阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。 例如,我们在socket中调用recv函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。

非阻塞:非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

对象的阻塞模式和阻塞函数调用:

对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状 态,在适当的时候调用阻塞函数,就可以避免阻塞。而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。函数select就是这样的一个例子。

总结为:

a.同步,就是我调用一个功能,该功能没有结束前,我死等结果。

b.异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)。

c.阻塞,就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。

d.非阻塞,就是调用我(函数),我(函数)立即返回,通过select通知调用者。

3.2同步和异步的实现

3.2.1阻塞通信

  

3.2.2非阻塞通信

实现非阻塞通信有两种方式,一种是利用异步方式,另一种使用多线程方式实现。两者的原理也是各不相同:

a.线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度;

b.异步本质上是计算机硬件功能,其操作无须消耗CPU时间的I/O操作;

编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,处理函数可以不必使用共享变量;

c.多线程是顺序执行,编程简单。但是线程的使用(滥用)会给系统带来上下文切换的额外负担。并且线程间的共享变量可能造成死锁的出现。

当需要执行I/O操作时,使用异步操作比使用线程+同步 I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.net Remoting 等跨进程的调用。

线程适用那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。

3.2.2.1多线程实现

    

3.2.2.2异步实现

   

4.809协议对接的实现

  

4.1TCP协议对接(部分)

由于TCP是长连接,所以这里需要用非阻塞方式通信,选择多线程方法解决:

  

4.2UDP协议对接(部分)

UDP不需保持连接状态,所以监听端口完成操作即可,由于接受消息后操作基本不耗时,所以没有启用多线程:

 

4.3对809协议解析的实现(部分)

  

5.总结

在研究生期间时,研究过一段时间的socket通信。当时对P2P模式,以及UDP打洞都还挺感兴趣。以后有机会和大家在一起探讨。

                            -----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

          如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^

                                      

轨迹系列——Socket总结及实现基于TCP或UDP的809协议方法的更多相关文章

  1. 轨迹系列7——Socket总结及实现基于TCP或UDP的809协议方法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在上一篇博客中我详细介绍了809协议的内容.809协议规范了通 ...

  2. 基于TCP和UDP的socket

    为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序中获取到另一个文件的 ...

  3. Java Socket实现基于TCP和UDP多线程通信

    一.通过Socket实现TCP编程 1.1 TCP编程 TCP协议是面向连接,可靠的,有序的,以字节流的方式发送数据.基于TCP协议实现网络通信的类有客户端的Socket类和服务器端的ServerSo ...

  4. JAVA Socket 底层是怎样基于TCP/IP 实现的???

    首先必须明确:TCP/IP模型中有四层结构:       应用层(Application Layer).传输层(Transport  Layer).网络层(Internet Layer  ).链路层( ...

  5. 基于TCP与UDP协议的socket通信

    基于TCP与UDP协议的socket通信 C/S架构与初识socket 在开始socket介绍之前,得先知道一个Client端/服务端架构,也就是 C/S 架构,互联网中处处充满了 C/S 架构(Cl ...

  6. Python网络编程02 /基于TCP、UDP协议的socket简单的通信、字符串转bytes类型

    Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes类型 目录 Python网络编程02 /基于TCP.UDP协议的socket简单的通信.字符串转bytes ...

  7. 初识Socket通信:基于TCP和UDP协议学习网络编程

    学习笔记: 1.基于TCP协议的Socket网络编程: (1)Socket类构造方法:在客户端和服务器端建立连接 Socket s = new Socket(hostName,port);以主机名和端 ...

  8. C++基于TCP和UDP的socket通信

    以下是关于socket编程的一个非常经典的例子: 服务端: #include <stdio.h> #include <Winsock2.h> //windows socket的 ...

  9. [Java网络安全系列面试题] 说一说TCP和UDP的区别与联系?

    TCP TCP是Transfer Control Protocol(传输控制协议)的简称,是一种面向连接的保证可靠传输的协议. 在TCP/IP协议中,IP层主要负责网络主机的定位,数据传输的路由,由I ...

随机推荐

  1. vue 项目中实用的小技巧

    # 在Vue 项目中引入Bootstrap 有时在vue项目中会根据需求引入Bootstrap,而Bootstrap又是依赖于jQuery的,在使用npm按照时,可能会出现一系列的错误 1.安装jQu ...

  2. C# winform 实现图片轮播

    作为一个C#winform刚刚入门的我  觉得这可能是初学者都会遇到的  我自己也觉得很神奇 首先 窗体里有一个Button按钮,和一个pictureBox 图片框 定义一个线程方法 /// < ...

  3. nodejs+mongoose+websocket搭建xxx聊天室

    简介 本文是由nodejs+mongoose+websocket打造的一个即时聊天系统:本来打算开发一个类似于网页QQ类似功能的聊天系统,但是目前只是开发了一个模块功能 --- 类似群聊的,即一对多的 ...

  4. 解决thymeleaf layout布局不生效

    今天使用thymeleaf layout布局时总是不生效,特此把解决问题的步骤和几个关键点记录下来备忘. 一.检查依赖 1.thymeleaf必备maven依赖: <dependency> ...

  5. sklearn的简单使用

    import numpy as np from sklearn import datasets from sklearn.cross_validation import train_test_spli ...

  6. Nova计算节点安装配置

    Nova计算节点安装配置 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ## Nova计算节点安装配置 #基本配置 ...

  7. Java爬虫实践--爬取CSDN网站图片为例

    实现的效果,自动在工程下创建Pictures文件夹,根据网站URL爬取图片,层层获取.在Pictures下以网站的层级URL命名文件夹,用来装该层URL下的图片.同时将文件名,路径,URL插入数据库, ...

  8. Yacc 与 Lex 快速入门(词法分析和语法分析)

    我们知道,高级语言,一般的如c,Java等是不能直接运行的,它们需要经过编译成机器认识的语言.即编译器的工作. 编译器工作流程:词法分析.语法分析.语义分析.IR(中间代码,intermediate ...

  9. The authenticity of host 'github.com (192.30.253.113)' can't be established.

    在初始化git之后(git init),同时在github建立好仓库之后,本地也新增了ssh kye(ssh-keygen -t rsa -C 'mail address'),同时也在本地新增了远程仓 ...

  10. javascript设计模式——装饰者模式

    前面的话 在程序开发中,许多时候都并不希望某个类天生就非常庞大,一次性包含许多职责.那么可以使用装饰者模式.装饰者模式可以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象.本文将 ...