UDP套接字和粘包

1.UDP套接字

  udp服务端:

1 ss = socket()           #创建一个服务器的套接字
2 ss.bind()                 #绑定服务器套接字
3 inf_loop:                 #服务器无限循环
4cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送)
5 ss.close()               # 关闭服务器套接字

  udp客户端:

1 cs = socket()           # 创建客户套接字
2 comm_loop:             # 通讯循环
3 cs.sendto()/cs.recvfrom()   # 对话(发送/接收)
4 cs.close()                # 关闭客户套接字

2.recv与recvfrom的区别:

  part1:

    发消息都是将数据发送到己端发送缓冲中,手消息都是从己端的缓冲区中收

    tcp:send发消息,recv收消息

    udp:sendto发消息,recvfrom收消息

  part2:

    tcp是基于数据流的,而udp是基于数据报的

    send(bytes_data):发送数据流,数据流bytes_data若为空,自己这段的缓冲区也为空,操作系统不会控制tcp协议发空包

    sendinto(bytes_data,ip_port):发送数据报,bytes_data为空,还有ip_port,所有即便是发送空的butes_data,数据报其实也不是空的,自己这端的缓冲区收到内容,操作系统就会控制udp协议发包.

  part3:

    1.tcp协议:

      (1)如果收消息缓冲区里的数据为空,那么recv就会阻塞(阻塞很简单,就是一直在等着接收)

      (2)只不过tcp协议的客户端send一个空数据就是真的空数据,客户端即使有无穷个send空,也跟没有一个样.

      (3)tcp基于链接通信

        *基于链接,则需要listen(backlog),指定半连接池的大小

        *基于链接,必须先运行的服务端,然后客户端发起链接请求

        *对于Mac空系统:如果一段断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端在收消息后加上if判断,空消息就break掉通信循环)

        *对于Windows/Linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法:服务端通信循环内加异常处理,捕捉到异常后就break掉通讯循环)

    2.udp协议

      (1)如果收消息缓冲区里的数据为"空",recvfrom也会阻塞

      (2)支部会udp协议的客户端sendinto一个空数据并不是真的空数据(包含:空数据+地址信息,得到的报仍然不会为空),所以客户端只要有一个sendinto(不管是否发送空数据,都不会真的空数据),服务端就可以recvfrom到数据.

      (3)udp无链接

        *无链接,因而无需listen(backlog),更加没有什么连接池之说了

        *无链接,udp的sendinto不用管是否有一个正在运行的服务端,可以己端一个劲的发消息,只不过数据丢失

        *recvfrom收的数据小于sendinto发送的数据时,在Mac和Linux系统上数据直接丢失,在Windows系统上发送的比接受的大直接报错

        *只有sendinto发送数据没有recvfrom收数据,数据丢失

  PS:

    1.你单独运行上面的udp的客户端,你发现并不会报错,相反tcp却会报错,因为udp协议只负责把包发出去,对方收不收,我根本管不着,而tcp是基于链接的,必须有一个服务端先运行着,客户端去跟服务端建立连接然后依托于连接才能传递消息,任何一方试图把连接摧毁都会导致对方程序崩溃

    2.上面的udp程序,你注释任何一条客户端的sendinto,服务端都会卡住,为什么?因为服务端有几个recvfrom就要对应几个sendinto,哪怕是sendinto(b‘‘)那也要有.

3.粘包现象:

  只有TCP有粘包现象,UDP永远不会粘包!

  所谓的粘包问题主要还是因为接收对方不知道消息之间的界限,不知道一次性提取多少字节的数据造成的.

  以下情况会发生粘包:

  1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,会合到一起,产生粘包)

  2.接收方不及时接收缓冲区的包,造成多个包接收(客户端发送一端数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

4.解决粘包方法:

  struct模块

  该模块可以把一个类型,如数字,转成固定长度的bytes

  >>>Struct.pack(‘i‘,111111111111)

  struct.error:‘i‘ format requires -2147483648 <= number <=2147483647 #这个是范围

时间: 2024-08-21 23:54:06

UDP套接字和粘包的相关文章

Day35:基于UDO的套接字、粘包问题

一.基于UDP的套接字 UDP服务端 ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 inf_loop: #服务器无限循环 cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送) ss.close() # 关闭服务器套接字 UDP客户端 cs = socket() # 创建客户套接字 comm_loop: # 通讯循环 cs.sendto()/cs.recvfrom() # 对话(发送/接收) cs.close() #

网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

TCP协议:三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立连接的请求 3:客户端接收到服务端发来的请求,返回接成功给服务端,完成双向连接 第一客戶向服务端发送请求,请求建立连接 服务端同客户端的请求,并同时向客户端发送建立 连接的请求,最后客户端同意后建立 双向连接. C ----> S C <---- S - 反馈机制: 客户端往服务端发送请求,服务端必须返回响应, 告诉客户

python基础--socket套接字、粘包问题

本地回环地址:127.0.0.1 简易版服务端: import socket ? server = socket.socket() # 就比如买了一个手机 server.bind(("127.0.0.1",8080)) # bind中绑定的是IP地址和端口号,注意是一个元组,就比如,将手机卡,插入了手机 server.listen(5) # 半连接池,最大等待连接数为5个,就比如开机 conn,address = server.accept() # 接听电话等着别人给你打电话 ? da

python开发socket网络编程基础:粘包问题&amp;udp套接字

一,发生粘包 服务器端 1 from socket import * 2 phone=socket(AF_INET,SOCK_STREAM) #套接字 3 phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #解决端口占用 4 phone.bind(('127.0.0.1',8080)) #绑定端口和Ip到套接字 5 phone.listen(5) 6 conn,client_addr=phone.accept() #等待tcp接受 7 8 9 # data1

TCP/UDP套接字网络协议

TCP服务端(以字节串传输信息) import socket 1.创建套接字 sockfd = socket.socket(socket_family = AF_INET,socket_type = SOCK_STREAM,proto = 0) 功能:创建一个IPv4的流式套接字,括号中的创建IPv4流式套接字的时候可以不写,有缺省值. 参数:socket_family 地址族类型 AF_INET 表示IPv4网络通信 socket_type 套接字类型 SOCK_STREAM 流式  SOCK

探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

【转】 探索UDP套接字编程

UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务,而TCP提供面向流.提供可靠数据服务.注意,UDP和TCP没有好坏之分,只是二者的适用场景不同罢了. 典型的UDP套接字编程模型是客户端不予服务端建立连接,而只是调用sendto函数来向服务端发送数据,其中必须要指定服务端的信息,包括IP和端口等:服务端不接收来自客户端的连接,而只是调用recvfr

Unix网络编程学习笔记之第8章 基于UDP套接字编程

一. UDP C/S的典型函数调用 UDP没有像TCP那样的连接,客户端直接sendto向某服务器发送数据,服务器端一直recvfrom阻塞,以接收任何客户端发送的数据. 二. sendto和recvfrom函数 int sendto(int sockfd, const void* buff, size_t nbytes, int flag, const struct sockaddr* to, socklen_taddrlen); int recvfrom(int sockfd, void*

udp套接字使用信号驱动式I/O

信号驱动式I/O的本质就是:进程预先告知内核当某个描写叙述符发生事件时,内核会向该进程发送SIGIO信号通知进程,进程可在信号处理函数中进行处理 进程能够通过fcntl打开O_ASYNC标志或ioctl打开FIOASYNC标志来通知内核,二者的差别是一些系统不支持fcntl,所以应尽量使用ioctl 对于TCP套接字产生SIGIO信号的条件: 1.监听套接字上有新连接请求完毕 2.某个断连请求发起 3.某个断连请求完毕 4.数据到达套接字 5.数据已从套接字发送走(输出缓冲区有空暇空间) 6.发