python udp_Python UDP实例

UDP通信过程

udp 不需要经过3次握手和4次挥手,不需要提前建立连接,直接发数据就行。

server端

import socket

BUFSIZE = 1024

ip_port = ('127.0.0.1', 9999)

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # udp协议

server.bind(ip_port)

while True:

data,client_addr = server.recvfrom(BUFSIZE)

print('server收到的数据', data)

server.sendto(data.upper(),client_addr)

server.close()

client端

import socket

BUFSIZE = 1024

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:

msg = input(">> ").strip()

ip_port = ('127.0.0.1', 9999)

client.sendto(msg.encode('utf-8'),ip_port)

data,server_addr = client.recvfrom(BUFSIZE)

print('客户端recvfrom ',data,server_addr)

client.close()

输出结果

server:

server收到的数据 b'hello'

server收到的数据 b'world'

client:

>> hello

客户端recvfrom b'HELLO' ('127.0.0.1', 9999)

>> world

客户端recvfrom b'WORLD' ('127.0.0.1', 9999)

>>

粘包分析

第一种:

server

from socket import *

import time

server=socket(AF_INET,SOCK_DGRAM)

server.bind(('127.0.0.1',8880))

res1=server.recvfrom(10) #b'hello'

print('第一次:',res1)

res2=server.recvfrom(1024) #b'world'

print('第二次:',res2)

server.close()

client

from socket import *

import time

client = socket(AF_INET, SOCK_DGRAM)

client.sendto(b'hello',('127.0.0.1',8880))

client.sendto(b'world',('127.0.0.1',8880))

client.close()

服务端结果:没有产生粘包

第一次: (b'hello', ('127.0.0.1', 63959))

第二次: (b'world', ('127.0.0.1', 63959))

第二种:

server:

from socket import *

import time

server=socket(AF_INET,SOCK_DGRAM)

server.bind(('127.0.0.1',8880))

res1=server.recvfrom(2) #b'he'

print('第一次:',res1)

time.sleep(6)

res2=server.recvfrom(1024) #b'world'

print('第二次:',res2)

server.close()

client:

from socket import *

import time

client = socket(AF_INET, SOCK_DGRAM)

client.sendto(b'hello',('127.0.0.1',8880))

time.sleep(5)

client.sendto(b'world',('127.0.0.1',8880))

client.close()

输出结果

windows直接报错:

Traceback (most recent call last):

/路飞/第三模块/第二章网络编程/06 基于udp协议的套接字/服务端.py", line 24, in

res1=server.recvfrom(2) #b'he'

OSError: [WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。

mac或linux:

直接丢包,只收到b'he',后面的llo不会收到

TCP VS UDP

tcp基于链接通信

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

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

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

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

udp无链接

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

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

recvfrom收的数据小于sendinto发送的数据时,在mac和linux系统上数据直接丢失,在windows系统上发送的比接收的大直接报错

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值