socket通信中tcp和udp包大小确定

本文详细解析了UDP和TCP协议如何利用端口实现数据传输,并介绍了最大传输单元(MTU)的概念及其在网络通信中的作用。此外,还讨论了不同场景下UDP和TCP数据包的大小限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 UDP和TCP协议利用端口号实现多项应用同时发送和接收数据。数据通过源端口发送出去,通过目标端口


接收。有的网络应用只能使用预留或注册的静态端口;而另外一些网络应用则可以使用未被注册的动态


端口。因为UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。动态端口的


范围是从1024到65535。  


    MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,EthernetII帧的结构


DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大


不能超过1518bytes,对于小于或者大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以


太网转发设备会丢弃这些数据帧。


    由于以太网EthernetII最大的数据帧是1518Bytes这样,刨去以太网帧的帧头(DMAC目的MAC地址


48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes那么剩下


承载上层协议的地方也就是Data域最大就只能有1500Bytes这个值我们就把它称之为MTU。


UDP 包的大小就应该是 1500 – IP头(20) – UDP头(8) = 1472(BYTES)
TCP 包的大小就应该是 1500 – IP头(20) – TCP头(20) = 1460 (BYTES)


注*PPPoE所谓PPPoE就是在以太网上面跑“PPP”。随着宽带接入(这种宽带接入一般为Cable Modem或者


xDSL或者以太网的接入),因为以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服


务进行认证计费的,所以引入PPPoE。PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的


开销(8Bytes),就变成1492。不过目前大多数的路由设备的MTU都为1500。


   如果我们定义的TCP和UDP包没有超过范围,那么我们的包在IP层就不用分包了,这样传输过程中就避


免了在IP层组包发生的错误;如果超过范围,既IP数据报大于1500字节,发送方IP层就需要将数据包分


成若干片,而接收方IP层就需要进行数据报的重组。更严重的是,如果使用UDP协议,当IP层组包发生错


误,那么包就会被丢弃。接收方无法重组数据报,将导致丢弃整个IP数据报。UDP不保证可靠传输;但是


TCP发生组包错误时,该包会被重传,保证可靠传输。


    UDP数据报的长度是指包括报头和数据部分在内的总字节数,其中报头长度固定,数据部分可变。数


据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字


节(64K)。


    我们在用Socket编程时, UDP协议要求包小于64K,TCP没有限定。


    不过鉴于Internet上的标准MTU值为576字节,所以建议在进行Internet的UDP编程时,最好将UDP的


数据长度控制在548字节 (576-8-20)以内。


就具体函数而言:


    用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) – UDP头(8)=65507


字节。用sendto函数发送数据时,如果发送数据长度大于该值,则函数会返回错误。 


    用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),


这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送


出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。
在 Python 中,`socket` 是用于实现网络通信的基础模块,支持 TCP UDP 两种主要协议。通过 `socket`,可以创建客户端与服务端程序,进行数据的发送与接收。 ### TCP 通信机制 TCP(Transmission Control Protocol)是一种面向连接的协议,提供可靠的数据传输。在 Python 中,TCP 通信通过 `socket.SOCK_STREAM` 类型实现。TCP 通信需要经过三次握手建立连接,并在通信结束后通过四次挥手断开连接。 服务端代码示例: ```python import socket # 创建 TCP 服务端套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 12345)) server_socket.listen(5) print("Server is listening...") # 等待客户端连接 conn, addr = server_socket.accept() print(f"Connected by {addr}") while True: data = conn.recv(1024) if not data: break print(f"Received: {data.decode()}") conn.sendall(data) # 回传数据 conn.close() ``` 客户端代码示例: ```python import socket # 创建 TCP 客户端套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 12345)) client_socket.sendall(b"Hello, Server!") response = client_socket.recv(1024) print(f"Response: {response.decode()}") client_socket.close() ``` ### UDP 通信机制 UDP(User Datagram Protocol)是一种无连接的协议,传输速度快但不保证数据的可靠送达。在 Python 中,UDP 通信通过 `socket.SOCK_DGRAM` 类型实现。由于 UDP 是无连接的,因此不需要建立断开连接的过程。 服务端代码示例: ```python import socket # 创建 UDP 服务端套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_socket.bind(('localhost', 12345)) print("Server is listening...") while True: data, addr = server_socket.recvfrom(1024) print(f"Received from {addr}: {data.decode()}") server_socket.sendto(data, addr) # 回传数据 ``` 客户端代码示例: ```python import socket # 创建 UDP 客户端套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_address = ('localhost', 12345) message = b"Hello, Server!" client_socket.sendto(message, server_address) response, server = client_socket.recvfrom(1024) print(f"Response: {response.decode()}") client_socket.close() ``` ### TCPUDP 的区别 1. **连接性**: - TCP 是面向连接的协议,通信前必须通过三次握手建立连接。 - UDP 是无连接的协议,直接发送数据,不需要建立连接。 2. **可靠性**: - TCP 提供可靠的数据传输,确保数据按序到达。 - UDP 不保证数据的可靠传输,数据可能丢失或乱序。 3. **流量控制与拥塞控制**: - TCP 具备流量控制拥塞控制机制,防止网络过载。 - UDP 没有这些机制,适用于实时应用,如视频流或在线游戏。 4. **速度与效率**: - TCP 的可靠性连接性导致其传输速度较慢。 - UDP 传输速度快,适合对实时性要求高的应用。 5. **应用场景**: - TCP 适用于需要可靠传输的场景,如网页浏览、文件传输等。 - UDP 适用于对速度效率要求较高的场景,如实时音视频传输、在线游戏等[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值