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

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处: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/

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

                                      

 

时间: 2024-09-29 09:17:26

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

实时通信 p2p-p2p聊天的基于tcp与udp的程序

问题描述 p2p聊天的基于tcp与udp的程序 基于tcp和udp两种协议的聊天程序,实现简单的实时通信,使用winsock 解决方案 http://blog.sina.com.cn/s/blog_6cbb09f3010161jn.html 解决方案二: http://www.pudn.com/downloads545/sourcecode/windows/network/detail2250746.html (pudn的下载,如果你采纳我的回答,我可以下载以后传给你)

Socket编程 (连接,发送消息) (Tcp、Udp) - Part1

原文 http://www.cnblogs.com/zengqinglei/archive/2013/04/27/3046119.html Socket编程 (连接,发送消息) (Tcp.Udp)  本篇文章主要实现Socket在Tcp\Udp协议下相互通讯的方式.(服务器端与客户端的通讯) 1.基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息. 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定服

C语言编写基于TCP和UDP协议的Socket通信程序示例_C 语言

Tcp多线程服务器和客户端程序服务器程序: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #define PORT 8082 #define BUFSIZE 512 char

TCP和UDP的&quot;保护消息边界&quot; (经典)

在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制.       对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbu

【转】关于TCP和UDP协议消息保护边界的介绍

在 socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包.这样,接收端,就难于分辨出来了,必须提供科学的拆包机制.对于UDP,不会使用块的合并优化算法,这样,实际上目前认为,是由于UDP支持的是一对多的模式,所以接收端的skbuff(套接

给产品经理讲技术,不得不懂的TCP和UDP

TCP/IP协议,你一定经常听说吧,其中TCP(Transmission Control Protocol)称为传输控制协议,IP(Internet Protocol)称为因特网互联协议,好吧,这都是什么2B名字,根本不知所云,这个时候,计算机科学对于一个没有经过深入研究的人,毫无用户体验可言. 其实TCP/IP协议,是一个协议簇,就是一大堆协议的集合,这一大套协议定义了整个互联网通信的基础,比如一次网络链接要经过哪些步骤,一块数据 传输过程中应该如何解释,这块数据该如何展示给编程者等等问题.就

tcp-C# 如何使用socket实现基于TCP协议传输数据

问题描述 C# 如何使用socket实现基于TCP协议传输数据 我使用Socket.Send和Socket.BeginReceive完成了上位机通讯软件的编写,但是连接下位机经过分析抓包软件得到的数据包,发现似乎与标准TCP协议有出入.具体来讲是这样的: 首先根据TCP协议,数据交换的规范应该是这样的http://blog.csdn.net/moonhnney/article/details/5604677 数据交换: a ---->b a 发送数据完毕,(PSH,ACK) aseq = x,a

Java基于Tcp协议的socket编程实例_java

本文实例讲述了Java基于Tcp协议的socket编程方法,分享给大家供大家参考.具体分析如下: 以下是一对一的通信编程实现,后续会继续学习一个服务器监听多个客户端的实现. 这里用到的主要步骤如下: 第一步:以特定端口(如4800)新建socket对象 第二步:以系统输入设备构造BufferedReader对象,该对象用于接收系统键盘输入的字符 第三步:以socket对象 得到输出流来构造PrintWriter 第四步:以socket对象得到输入流来构造相应的BufferedReader对象,该

VC面向对象的方式 写一个基于TCP的 客户端服务端程序 (SOCKET)

SOCKET accept( SOCKET s, struct sockaddr FAR*addr, int FAR *addrlen);   //最后一个参数一定要赋值为 SOCKADDR结构体的长度 否则调用失败 这个MSDN的解释有     SOCKET是网络编程的接口   目前的C/S模式的开发都是基于 SOCKET 的   TCP服务器编写流程  :   创建socket----------->配置SOCKADDR_IN 并调用bind()函数绑定到socket----------->