第六章

UDP协议

    服务端

 1 '''
 2 UDP 协议 又称 数据报协议 SOCK_DGRAM
 3 
 4 '''
 5 from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
 6 
 7 server = socket(AF_INET,SOCK_DGRAM)
 8 server.bind(('127.0.0.1',8080))  # IP和端口 要绑定 服务端固定的IP端口
 9 # server.listen() # 不需要 挂起的链接数 udp 没连接
10 
11 # server.accept()  # 不需要 因为udp就没连接
12 # while True:
13 #     conn,addr = server.accept()  # 干连接循环的活
14 
15 while True:
16     data,client_addr = server.recvfrom(1024)
17     print('客户端数据:',data)  # 我要知道谁给我发的
18     '''
19     (b'data', ('127.0.0.1', 51182))
20     (b'hello', ('127.0.0.1', 51182))
21     '''
22     server.sendto(data.upper(),client_addr)
23 
24 server.close()

客户端

 1 '''
 2 udp 可以发空 数据报协议 说是发空,其实不是空 ,还有一个IP 端口的信息,发空时 带个端口信息
 3 tcp:不是一一对应的
 4 udp:是一一对应的 数据报 完整的
 5 '''
 6 from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
 7 
 8 client = socket(AF_INET,SOCK_DGRAM)
 9 # server.bind('127.0.0.1',8080)  # IP和端口 要绑定 服务端固定的IP端口
10 # server.listen() # 不需要 挂起的链接数 udp 没连接
11 
12 # server.accept()  # 不需要 因为udp就没连接
13 # while True:
14 #     conn,addr = server.accept()  # 干连接循环的活
15 
16 while True:
17     msg = input('>>>:').strip()  # udp 可以发空 收到一个空
18     # if not msg:continue
19     client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))  # 明确的指定发给谁 因为没有连接了
20 
21     data,server_addr = client.recvfrom(1024)
22     print('服务端返回的数据:',data,'服务端的地址:',server_addr)
23 server.close()

不会粘包的UDP

服务端:
 1 # -*- coding:utf-8 -*-
 2 '''
 3 UDP 协议 又称 数据报协议 SOCK_DGRAM
 4 sendto recvfrom 一一对应 数据报协议 没有粘包问题 udp 数据不安全 有可能发送数据 > 1024 或者网络异常 数据没了
 5 tcp: 数据一定要可靠
 6     远程执行命令
 7     下载文件
 8 udp协议:
 9     QQ
10     查询操作eg:互联网上 查询时间  ntp时间服务器 udp协议 eg:查域名 转成ip 端口 dns服务器走的就是udp协议  能保证查询效率高 数据虽然不可靠
11     ntp时间服务器 dns服务器 qq 都是udp
12 '''
13 # from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
14 #
15 # server = socket(AF_INET,SOCK_DGRAM)
16 # server.bind(('127.0.0.1',8080))  # IP和端口 要绑定 服务端固定的IP端口
17 #
18 # res1 = server.recvfrom(1024)
19 # print('第一次:',res1)
20 # res2 = server.recvfrom(1024)
21 # print('第二次:',res2)
22 
23 from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
24 
25 server = socket(AF_INET,SOCK_DGRAM)
26 server.bind(('127.0.0.1',8080))  # IP和端口 要绑定 服务端固定的IP端口
27 
28 res1 = server.recvfrom(4)
29 print('第一次:',res1)
30 res2 = server.recvfrom(1024)
31 print('第二次:',res2)

客户端:
 1 '''
 2 udp 可以发空 数据报协议 说是发空,其实不是空 ,还有一个IP 端口的信息,发空时 带个端口信息
 3 tcp:不是一一对应的
 4 udp:是一一对应的 数据报 完整的额 
 5 '''
 6 # from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
 7 #
 8 # client = socket(AF_INET,SOCK_DGRAM)
 9 #
10 # client.sendto(b'hello',('127.0.0.1',8080))
11 # client.sendto(b'world',('127.0.0.1',8080))
12 # client.close()
13 
14 from socket import *  # 一般不这样做 会重名 但写socket可以这样写 因为要用到太多 会有大量的socket.
15 
16 client = socket(AF_INET,SOCK_DGRAM)
17 
18 client.sendto(b'hello',('127.0.0.1',8080))
19 client.sendto(b'world',('127.0.0.1',8080))
20 client.close()

TCP VS UDP

tcp基于链接通信

  • 基于链接,则需要listen(backlog),指定连接池的大小
  • 基于链接,必须先运行的服务端,然后客户端发起链接请求
  • 对于mac系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端在收消息后加上if判断,空消息就break掉通信循环)
  • 对于windows/linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法是:服务端通信循环内加异常处理,捕捉到异常后就break掉通讯循环)
  • 流式协议  会粘包  不可以发空 send recv 不是 一 一对应
  • tcp适用于:
    • 数据一定要可靠
    • 远程执行命令
    • 下载文件

udp无链接

  • 无链接,因而无需listen(backlog),更加没有什么连接池之说了
  • 无链接,udp的sendto不用管是否有一个正在运行的服务端,可以己端一个劲的发消息,只不过数据丢失
  • recvfrom收的数据小于sendto发送的数据时,在mac和linux系统上数据直接丢失,在windows系统上发送的比接收的大直接报错
  • 只有sendto发送数据没有recvfrom收数据,数据丢失
  • 数据报协议  不会粘包 可以发空 sendto recvfrom 一 一 对应  数据报协议  数据不安全 有可能发送数据 > 1024 或者网络网络异常 数据没了
  • udp适用于
    • QQ
    • 查询操作  eg: ntp时间服务器  dns服务器(查域名,转ip)  能保证查询效率高,数据虽然不可靠 
原文地址:https://www.cnblogs.com/mumupa0824/p/9016469.html