文章目录
TCP/UDP协议详解
简介
TCP协议简介
TCP:Transmission Control Protocal传输控制协议
- 是一种面向连接的、可靠的、基于字节流的传输层通信协议。
- TCP旨在适应支持多网络应用的分层协议结构
- 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。
TCP的功能
- 接受来自应用层的8位字数据流,并将其分割成适当长度的报文段,然后传给网络层(IP层)。
- 为了保证报文传输的可靠,TCP给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
- 然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
- 在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。
- 在保证可靠性上,采用超时重传和捎带确认机制。
- 在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。
UDP协议简介
User Datagram Prorocol:用户数据报协议
- UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法
- UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。
- UDP Helper可以实现对指定UDP端口广播报文的中继转发,即将指定UDP端口的广播报文转换为单播报文发送给指定的服务器,起到中继的作用。
UDP的功能
- UDP层的报头指明了主机上的源端口和目的端口
- UDP传输的段(segment)有8个字节的报头和有效载荷字段构成
- UDP报头由4个域组成,其中每个域各占用2个字节,具体包括源端口号、目标端口号、数据报长度、校验值。
套接字
-
**套接字(Socket)**是应用层进程与计算机网络层之间的接口。
-
进程通过套接字接收和发送报文。
-
套接字是建立网络应用程序的可编程接口,故也称为应用程序和网络之间的应用程序编程接口(API)。
-
应用程序可以控制套接字在应用层端的一切,但是对于该套接字的运输层端几乎没有控制权。
应用层与TCP/UDP的关系
应用层对于传输层的控制权
应用程序开发者对于运输层的控制仅限于:
- 选择运输层的协议:在因特网中选择为TCP或UDP中的一种
- 也许能设定几个运输层参数,如最大缓存和最大报文段长度等。
- 一旦应用程序开发者选择了一个运输层协议,则应用程序就建立在由该协议提供的运输层服务之上。
可供应用程序使用的运输服务
-
套接字作为应用程序和运输层协议之间的接口。
-
在发送端的应用程序将报文推进套接字,在套接字的另一侧,运输层协议负责从接收进程的套接字得到该报文。
-
当开发一个应用时,必须选择一种可用的运输层协议。
总的来说,运输层能够为应用程序提供四种服务:
1.可靠数据传输
- 分组在传输过程中可能丢失,对于像电子邮件、Web文档、金融应用等应用对于数据丢失的容忍限度很低。
- 为支持这些应用,如果一个协议提供了确保数据正确完全地交付到另一端,则这个协议称为可靠数据传输协议。
- 运输层协议能够潜在地向应用程序提供的一个重要服务是进程到进程的可靠数据传输。值得注意的是,发送进程只要将其数据传递进套接字,就可以完全相信该数据将能无差别地到达接收进程。
- 相反的,如果一个运输层协议不提供可靠数据传输是,由该发送进程发送的某些数据可能到达不了该接收进程,典型的如UDP,这可能能被容忍丢失的应用所接收。
2.吞吐量
- 考虑到其他会话将会共享沿着该网络路径的带宽,并且这些会话将会到达和离开,可用吞吐量将会随时间波动。
- 某些服务需要运输层能够克服这种波动,及运输层协议能够以某种特定的速率提供确保的可用吞吐量。
- 具有吞吐量要求的应用被称为带宽敏感应用。如某些多媒体应用程序。
- 相对的,弹性应用能够根据当时可用的带宽或多或少地利用可供使用的吞吐量。如:电子邮件、文件传输以及Web传送。
**带宽:**即网络带宽,在单位时间(一般指的是1秒钟)内能传输的数据量。
可用吞吐量:发送进程能够向接收进程交付比特的速率。
3.定时
- 运输层协议能够提供定时保证。
- 这种服务对于交互式实时应用程序具有很大的吸引力,如因特网电话、虚拟环境、电话会议和多方游戏。所有这些服务为了有效性而要求数据交付有严格的时间限制。
- 游戏的卡顿和视频的不流畅将会丧失真实感。
4.安全性
- 在发送主机中,运输协议能够加密由发送进程传输的所有数据。
- 在接收主机中,运输层协议能够在将数据交付给接收进程之前将数据解密。
因特网提供的运输服务
-
因特网为为应用程序提供了两个运输协议,即UDP和TCP。
-
当你作为软件开发者为因特网创建一个新的应用时,首先要决定选择UDP还是TCP。
-
每个协议为调用它的应用程序提供了不同的服务集合
应用 | 数据丢失 | 带宽 | 时间敏感 |
---|---|---|---|
文件传输 | 不能丢失 | 弹性 | 不 |
电子邮件 | 不能丢失 | 弹性 | 不 |
Web文档 | 不能丢失 | 弹性(几kbps) | 不 |
因特网电话/视频会议 | 容忍丢失 | 音频(几kbps~1Mbps) | |
视频(10kbps~5Mbps) | 是,100ms | ||
流式存储音频/视频 | 容忍丢失 | 同上 | 是,几秒 |
交互式游戏 | 容忍丢失 | 几kbps~10kbps | 是,100ms |
智能手机讯息 | 不能丢失 | 弹性 | 不确定 |
TCP服务
面向连接的服务
- 在应用层数据报文开始流动之前,TCP让客户和服务器互相交换运输层控制信息。
- 这个过程为握手,同时提醒客户和服务器,为大量分组的到来做准备。
- 在握手阶段后,一个TCP连接就在两个进程的套接字之间建立了。
- 这条连接是全双工的,即连接双方的进程可以在此连接上同时进行报文收发。
- 当应用程序结束报文发送时,必须拆除该连接。
可靠的数据传送服务
- 通信进程能够依靠TCP,无差别、按适当顺序交付所有发送的数据。
- 当应用程序的一段将字节流传进套接字时,它能够依靠TCP将相同的字节流交付给接收方的套接字,而没有字节的丢失和冗余。
拥塞控制机制
- 这种服务不一定能够为通信进程带来好处,但能为因特网整体带来好处。
- 当接收方和发送方之间的网络出现拥塞时,TCP的拥塞控制机制会抑制发送进程。
- TCP拥塞控制也试图限制每一个TCP连接,使它们达到公平共享网络宽带的目的。
TCP安全
- 无论是TCP还是UDP都没有提供任何加密机制
- 由于安全和隐私问题至关重要,所以因特网界已经研制了TCP的加强版本,称为安全套接字(Secure Sockets Layer,SSL)。
- 用SSL加强的TCP不仅能够做传统的TCP所能做的一切,而且提供了关键的进程到进程的安全性服务,包括加密、数据完整性和断电鉴别。
- SSL不是与TCP和UDP在相同层次上的第三种因特网运输协议,而是一种对TCP的加强,这种强化是在应用层上实现的。
- SSL有他自己的套接字API,这类似于传统的TCP套接字API。
UDP服务
- UDP是一种不提供不必要不必要服务的轻量级运输协议,他仅提供最小服务。
- UDP是无连接的,因此在两个通信前没有握手过程。
- 当一个进程将报文送进UDP套接字时,UDP协议并不保证该报文将到达接收进程。
- 不仅如此,接收进程的报文也可能是乱序到达的。
应用 | 支撑的运输协议 |
---|---|
电子邮件 | TCP |
远程终端访问 | TCP |
Web | TCP |
文件传输 | TCP |
流式多媒体 | TCP |
因特网电话 | TCP / UDP |
UDP套接字编程
简单的UDP Client-Server程序
UDPClient.py
from socket import *
serverName = 'hostname'//主机名
serverPort = 12000//端口号
clientSocket = socket(AF_INET,SOCK_DGRAM)//设置为SOCK_DGRAM即**UDP类型**
message = raw_input('Input sentence:')
slientSocket.sendto(message.encode(),(serverName,serverPort))//发送
modifiedMessage , serverAddress = clientSocket.recvfrom(2048)//取缓存长度2048作为收入,同时有信息和地址项
clientSocket.close()//关闭套接字
UDPServer.py
from socket import *
serverPort = 12000//端口号
serverSocket = socket(AF_INET,SOCK_DGRAM)
serverSocket.bind('',serverPort)//将端口号与服务器套接字绑定
print("The Server is ready to receive")
while True:
message , clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = Modifie(message.decode())//调用函数处理数据
serverSocket.sendto(modifiedMessage.encode(),clientAddress)
TCP套接字编程
TCPClient.py
from socket import *
serverName = 'servername'
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_STREAM)//设置为SOCK_STREAM类型,则为TCP类型套接字而非UDP
clientSocket.connect((serverName,serverPort))//需要先连接服务器
sentence = raw_input('Input sentence:')
clientSocket.send(sentence.encode())
modifiedSentence = clientSocket.recv(1024)//与UDP不同,只接收地址
print('From Serrver:',modifiedSentence.decode)
clientSocket.close()
TCPServer
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
serverSocket.listen(1)//设置请求连接的最大数为1
print('The server is ready to receive')
while True:
connectionSocket , addr = serverSocket.accept()
sentence = connectionSocket.recv(1024).decode()
capitalizedSentence = Motify(sentence)
connectionSocket.send(capitalizedSentence.encode())
connectionSocket.close()