《Python网络编程》学习笔记--UDP协议
第二章中主要介绍了UDP协议
UDP协议的定义(转自百度百科)
UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务的简单不可靠信息传送服务。UDP 协议基本上是IP协议与上层协议的接口。UDP协议适用端口分别运行在同一台设备上的多个应用程序。
UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。常用的UDP端口号有:
DNS(53) TFTP(69) SNMP(161)
UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如DNS、TFTP、SNMP等。
UDP在IP报文中的位置如图所示。
端口号
无符号16位数(0-65536)其中知名端口(0-1023)、注册端口(1024-49151)、其余端口(49152-65535)
Source(IP:port number) ->Destination(IP:port number)
在python中可以使用socket模块的getservbyname()函数获取知名端口名对应的端口号例如
import socket socket.getservbyname('domain')
Out[4]: 53
socket.getservbyname('http')
Out[5]: 80
套接字
在设计网络编程API时,Python标准库在底层对兼容POSIX操作系统(注:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX ),如LInux和MacOS)网络操作的底层系统调用进行了封装,并未所有普通的原始调用提供了一个简单的基于对象的系统。封装后的Python函数名与原始系统调用名相同。Python的这种设计使开发者可以使用早已熟知的方法来调用传统系统。
无论对于WIndows还是POSIX系统,网络操作背后的系统调用斗神围绕着套接字(Socket)这一概念进行的。
套接字是一个通信端点,操作系统使用整数标识套接字,而Python使用socket.socket对象来更方便的表示套接字,该对象内部维护了操作系统标识套接字的整数(可以调用它的fileno()方法来查看),每当调用socket.socket对象的方法请求使用该套接字的系统调用时,该对象都会自动使用内部维护的套接字整数标识符。
根据书上的代码,我们可以建立一个简单的UDP客户端
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter02/udp_local.py
# UDP client and server on localhost import argparse, socket
from datetime import datetime MAX_BYTES = 65535 def server(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', port))
print('Listening at {}'.format(sock.getsockname()))
while True:
data, address = sock.recvfrom(MAX_BYTES)
text = data.decode('ascii')
print('The client at {} says {!r}'.format(address, text))
text = 'Your data was {} bytes long'.format(len(data))
data = text.encode('ascii')
sock.sendto(data, address) def client(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = 'The time is {}'.format(datetime.now())
data = text.encode('ascii')
sock.sendto(data, ('127.0.0.1', port))
print('The OS assigned me the address {}'.format(sock.getsockname()))
data, address = sock.recvfrom(MAX_BYTES) # Danger! See Chapter 2
text = data.decode('ascii')
print('The server {} replied {!r}'.format(address, text)) if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive UDP locally')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('-p', metavar='PORT', type=int, default=1060,
help='UDP port (default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.p)
使用powshell(Windows下(目录有空格转义居然是用`,试了\半天0.0)定位到当前目录
输入
python udp_local.py server #udp_local.py是本文件名
当然如果端口被占用(例如本例子中的1060)会提示
Traceback (most recent call last):
File "udp_local.py", line 44, in <module>
function(args.p)
File "udp_local.py", line 14, in server
sock.bind(('127.0.0.1', port))
OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
之后再打开一个shell定位到当前页面输入
python udp_local.py client
会显示
The OS assigned me the address ('0.0.0.0', 59457)
The server ('127.0.0.1', 1060) replied 'Your data was 38 bytes long'
而server窗口同时显示
The client at ('127.0.0.1', 59457) says 'The time is 2018-01-15 16:24:19.498818'
而如果server已关闭本条指令会在powershell显示
The OS assigned me the address ('0.0.0.0', 50859)
Traceback (most recent call last):
File "udp_local.py", line 44, in <module>
function(args.p)
File "udp_local.py", line 31, in client
data, address = sock.recvfrom(MAX_BYTES) # Danger! See Chapter 2
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
程序中使用了sock.sendto()函数(需要指定地址和端口)
使用了sock.getsockname()调用查看IP地址和端口号,在输出中我们可以看出在这里分配的是59457端口
混杂客户端与垃圾回复
从上面的程序中我们也能明显看出,这样的程序实际上是相当危险的,在客户端等待服务器的响应时(在windows下可以通过发送响应中添加time.sleep()实现)我们可以向客户端程序发送一个‘伪造的信息’,如
>>>import socket
>>>sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
>>>sock.sendto('FAKE'.encode('ascii'),('127.0.0.1',59457))
客户端会立即结束等待,并将此响应看为服务器的响应
像这样不考虑地址是否正确,接受并处理所有收到的数据包的网络监听客户端在技术上叫做混杂(promiscuous)客户端,在这里是一种问题。但是当我们进行网络监控时,需要监控到达某一接口的所有数据包时会故意使用这种客户端。
优秀的加密方法,才可以保证程序与正确的服务器进行通信。但是当无法做到时,可以使用以下两种方案
- 设计或使用在请求中包含唯一标识符或请求ID的协议
- 检查响应数据包的地址与请求数据包的地址是否相同,也可以使用connect()来阻止其他地址向客户端发送数据包
《Python网络编程》学习笔记--UDP协议的更多相关文章
- python 网络编程 tcp和udp 协议
1. 网络通信协议 osi七层,tcp\ip五层 tcp\ip五层 arp协议:通过IP地址找到mac地址 2.tcp和udp的区别 tcp协议:面向连接,消息可靠,相对udp来讲,传输速度慢,消息是 ...
- python网络编程学习笔记(三):socket网络服务器(转载)
1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象 建立socket对 ...
- python网络编程学习笔记(10):webpy框架
转载请注明:@小五义http://www.cnblogs.com/xiaowuyi django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站. ...
- 转 网络编程学习笔记一:Socket编程
题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...
- python网络爬虫学习笔记
python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...
- JAVA UDP网络编程学习笔记
一.UDP网络编程概述 采用TCP协议通信时,客户端的Socket必须先与服务器建立连接,连接建立成功后,服务器端也会持有客户端连接的Socket,客户端的Socket与服务器端的Socket是对应的 ...
- python 之 网络编程(基于UDP协议的套接字通信)
8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...
- python网络编程学习《一》
最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以 ...
- python网络爬虫学习笔记(一)Request库
一.Requests库的基本说明 引入Rquests库的代码如下 import requests 库中支持REQUEST, GET, HEAD, POST, PUT, PATCH, DELETE共7个 ...
随机推荐
- LibreOJ NOI Round #1 Day 1 B. 失控的未来交通工具
瞬间移动 官方题解 题意:一个带边权无向图,加边以及询问在 x,x+b,...,x+(c−1)bx,x+b,...,x+(c-1)bx,x+b,...,x+(c−1)b 这些数中,有多少存在一条与之模 ...
- 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】
Balala Power! Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- HDU 1014 Uniform Generator【GCD,水】
Uniform Generator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- c语言基础学习03
=============================================================================涉及到的知识点有:编码风格.c语言的数据类型. ...
- 一步一步从原理跟我学邮件收取及发送 4.不同平台下的socket
既然是面向程序员的文章那当然不能只说说原理,一定要有实际动手的操作. 其实作为我个人的经历来说,对于网络编程,这是最重要的一章! 作为一位混迹业内近20年的快退休的程序员,我学习过很多的开发语言 ...
- 使用layui在规定的期限内选择日期
这几天碰到了layui中的日期与时间这个,本以为很简单的,可是又一个需求是这样的,有两个日期选择框,第一个日期选择框要求最小日期不得小于当前日期,第二个日期选择框要求最小日期为第一个日期选择框的选中日 ...
- v-for并判断当前元素是否选中:$set实现响应添加属性
前言 一直纠结着使用v-for进行列表渲染时如何为当前的元素添加是否选中的标识. 1.v-for进行列表渲染 <div class="lists"> <ul> ...
- 地图API地址 百度地图开放平台
http://lbsyun.baidu.com/index.php?title=jspopular
- FORM ACTION=""
FORM ACTION="" 如果什么都不写,就表示提交到当前页
- OOAD之策略模式(1)
在引入策略模式之前.先用一个小项目解释为什么要有策略模式.这是一个模拟鸭子的小游戏.最开始需求为,所有的鸭子都会叫以及都会游泳且叫声游泳姿势都一样.因此我们用原始OO的思维去编写代码时很容易做到 pu ...