python网络编程基础
目录
标签(空格分隔): 网络编程
目录
tcp和udp
1、udp
tcp、udp是第四层传输层拥有的协议,用于在完成寻址功能后的数据传输。传输层将路由交换层和应用数据层划分开,主要提供数据传输控制。
udp的使用是面向无连接的,即协议自身的设计是不保证数据的有序性和重传的,这样的缺点是丢包率增加,并且无法有序的接收数据。不过这两个缺点都可以通过应用层来弥补。而udp的优点是报头小、数据传输效率高(不需要确认、协商各种流控制等等),所以udp更适用于数据需要快速传输,并对数据完整性并不太高的场景。比如:视频直播,要求实时传输,而且可以接受部分的丢帧。
udp报头非常的简单,核心只有端口+校验和
2、tcp
tcp的使用是面向连接的,即数据的传输必须基于虚链路的完整建立。虚链路的建立提供了很多优秀的功能,比如确认重传以保证数据的完整性,滑动窗口以保证数据传输的高效性,各类选项字段提供不同的可选功能。tcp的缺点是报头大,因为需要包含比udp更多的功能字段,而且tcp数据的每次发送都必须得到确认否则将会重传。tcp一般应用于对数据完整性要求很高的场景。比如:ssh。
tcp的报头字段比较多,核心有:seq和ack用于处理确认重传、SYN/FIN/RST等用于提供数据包身份标记、窗口用于处理流量控制、还有各种选项。
3、socket函数
为了将路由交换和应用层分离开,socket提供了一个统一的接口供应用层直接调用而无需考虑底层路由交换的通信问题。
所有的操作系统都提供socket调用,python的socket模块也是对底层socket模块的封装,并提供了方便使用的一些函数接口。
1、建立对象
# 实例化一个socket对象,用于处理本地的socket事务,不论是服务器还是客户端都一样 # socket模块提供了很多不同类型的socket,这里选择tcp,使用ipv4 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2、bind
# socket对象可以绑定本地的ip和端口号,这个函数在服务器和客户端均可使用,不过一般不会绑定客户端 # 客户端的ip和端口一般使用随机。 # 服务器一般会固定ip和端口以供大量客户端连接 # 服务器提供的ip会通过dns发布域名 # bind的参数是一个ip+port的元组,如果没有提供ip,则会监听本机所有对外接口ip sock.bind(('127.0.0.1', 8080))
3、listen
# 此函数只应该用于服务器,因为服务器才需要监听端口等待客户主动连接 # 此函数将会告知操作系统监听socket连接 # 此函数的底层操作应该就是完成tcp三次握手 # 此函数的5表示已经完成三次握手的客户端最大数量,但是这些客户端还未与服务器交互数据 sock.listen(5)
4、connect
# 此函数只应该用于客户端,因为客户端才需要连接服务器的端口 # 此函数一旦启动,则会在客户端上随机选取本地端口 # 此函数的语义是发起tcp三次握手 sock.connect(('127.0.0.1', 8080))
5、accept
# 此函数应该用于服务器,当tcp三次握手完成之后,服务器通过此函数获取此客户端socket对象和地址。 # 此函数是一个阻塞函数,即,如果服务器没有任何虚链路完成,将会无限阻塞,直到有一个虚链路通过 # listen完成,accept才会返回。 # 如果要服务器提供无限接收客户端的功能,应该循环此函数以提供链路循环 conn, addr = sock.accept()
6、recv
# 此函数用于从一个socket对象(管道)中获取数据,而实际上,是从操作系统的网卡缓存中获取数据 # 可以指定需要一次获取的字节数,获取得到的数据是bytes类型,需要decode才方便阅读 # 此函数是一个阻塞函数,即,如果网卡缓存没有任何数据,则会一直阻塞到数据到达为止 msg = conn.recv()
7、send
# 此函数用于将bytes类型的数据发送给socket对象(管道),而实际上,是发送给网卡缓存,后续交由 # 操作系统真正的发送数据。 # 此函数非阻塞,可以直接返回,不过要特别注意的是,msg如果为空,此函数可以正确执行,但是实际上 # 操作系统是没有发送数据给对端的。这样会产生一些socket连接的问题,所以要杜绝发空。 conn.send(msg)
8、close
# 关闭虚链路 conn.close()
9、getpeername
# 获取一个虚链路对端的地址二元组 print(sock.getpeername())
4、粘包问题
根本原因:tcp面向流,无法区分消息之间的数据边界,固定recv就会导致消息粘包
解决思路:每次recv的时候动态获取,并准确的获取一个消息的长度
解决办法:每一个消息都增加固定长度的报头。每次recv的时候先获取固定长度的报头,从报头中获取本次消息的准确长度,然后再recv完整准确的信息。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
面试 5:手写 Java 的 pow() 实现
我们在处理一道编程面试题的时候,通常除了注意代码规范以外,千万要记得自己心中模拟一个单元测试。主要通过三方面来处理。 功能性测试 边界值测试 负面性测试 不管如何,一定要保证自己代码考虑的全面,而不要简单地猜想用户的输入一定是正确的,只是去实现功能。通常你编写一个能接受住考验的代码,会让面试官对你刮目相看,你可以不厉害,但已经充分说明了你的靠谱。 今天我们的面试题目是: 面试题:尝试实现 Java 的 Math.pow(double base,int exponent) 函数算法,计算 base 的 exponent 次方,不得使用库函数,同时不需要考虑大数问题。 面试题来源于《剑指 Offer》第 11 题,数字的整数次方。 不要介意 Java 真正的方法是 Math.pow(double var1,double var2)。 由于不需要考虑大数问题,不少小伙伴心中暗自窃喜,这题目也太简单了,给我撞上了,运气真好,于是直接写出下面的代码: public class Test11 { private static double power(double base, int expone...
- 下一篇
跨域访问
对于跨域访问的问题,以前一直没有深入的研究, 就记得放回一个XML来支持跨域的问题。今天,一个同事问我关于跨域请求的问题,我仔细的查阅了一下资料,对于网络上的一些知识的理解,特总结如下。 对于flash跨域,在服务器端返回如下XML文件。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> <!-- Policy file for xmlsocket://socks.adobe.com --> <cross-domain-policy> <site-control permitted-cross-domain-policies="all" /> <allow-access-from domain="*" to-ports="*" /> <allow-http-request-headers-f...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果