看过那么多python写的socket的例子后,还是要看一下官网上的文章

本文从官方文档《Socket Programming HOWTO》中提炼了八大关键知识点,包括client socket的一次性使用、通讯处理的三种模式、缓冲区原理、连接关闭的判断、信息处理方法、字节序转换、对端socket挂掉的处理以及非阻塞模式与select的配合使用。这些知识点揭示了Python socket编程中的核心概念和实践策略。
摘要由CSDN通过智能技术生成

这两天在练习用python写socket的小程序,浏览了挺多博客,感觉好像直接举例的多;基本没有人具体说socket编程应该遵守一个什么模式,如何在程序或者项目中使用,还有那些事情要注意的地方。

我觉得有可能有两点原因:
1、socket这个知识点大家可能都学过,所以大多数人都是把自己练习的例子贴出来,但是没有真正用在自己的项目中;
2、socket内容太多,真正用起来是属于比较底层的“基础设施”,在一些公司里可能都是用C语言或者更注重效率的方式实现的,这个知识点就变成不是大家关注的热点。

所以socket编程,可能是因为上手快,但是没有应用场景,所以看多了博文,觉得例子大同小异,对我的启发有限。

因为想多了解一些如何使用socket进行通讯,所以这两天由返回到官网上找到了这篇文章《Socket Programming HOWTO》
在这里插入图片描述
说实话,当时看到这篇文章的时候,光看了个题目,觉得可能没啥东西,就用题目搜了一下,结果下载到一篇PDF。当时还是想找找中文的资料,就没注意PDF的内容。但是中文资料确实没啥我想要的信息,所以今天就有回头看这个PDF。

打开PDF,结果第一眼就看到了大牛的名字,说实话,这一下就让我不淡定了。虽然这篇文章的作者是:Gordon McMillan,但是有Guido名字作为背书,我选择好好看一看这个文章。
在这里插入图片描述

第一个知识点

多数client socket 只用于一次信息交换。在这里插入图片描述
这个确实不是我之前理解的样子。我之前可能把socket当作类似session这样,能保持一种连接状态,持续不断的完成服务端和客户端的信息交互(当然也可以,不是说不行,只是文章中说一般只用来交互一次)。我就觉得这种情况下,要处理的异常场景太多了:服务端挂了怎么办,客户端怎么知道?客户端挂了,服务端怎么知道?一个socket挂了,怎么重新连?信息从什么地方开始重新传?这些问题不是无解,而是会因为这些问题导致通讯程序越写越大,越写越复杂。让人不安:处理这些异常的方式是否正确?是否还有哪些异常没有考虑?

但是如果一个client socket只用于一次交换,那么通讯这个场景就变得简化了:client socket建立一次连接,发送一次数据,搞定收工。其他还要信息的话,在来一次这样的连接,发送操作。这种方式确实简单了许多。

第二个知识点

socket完成连接后,可以有三种方式处理具体的通讯工作。在这里插入图片描述
1、使用线程;
2、使用进程;
3、使用non-blocking模式,配合select这种系统调用的方式。

虽然作者没有具体举例子,但是他已经划出了三条道。一般人估计跳不出这三条道,这应该算是总结了具体通讯的三种模式。

第三知识点

我们用send和recv操作的是缓冲区,而不是具体的信息字节。
在这里插入图片描述我的说法是有点不清楚,我就说一个例子。下午我在试验的时候,通过客户端在一个循环里给服务端发送了四次“nihao”,

for i in range(1,5)
	clientSocket.send("nihao")

服务端收到了什么?直接一次收到了四个连在一起的“nihaonihaonihaonihao”,这个例子就说明,我发送时,send(),将信息发送到了缓冲区,recv也是通过缓冲区获取的信息。并不是按照我的想法,发一个nihao,收一个nihao。当然看到试验结果的时候能够猜到确实有缓冲,但是上面这段文字证实了对缓冲区理解,我觉得对未来编程还是是有帮助的。

第四个知识点

当另一端socket关闭时,这一端的socket调用recv 会返回0字节。
在这里插入图片描述
这也就大家常用来进行是否接收结束的的条件:

data = connSock.recv(1024)
if data:
	# 打印数据
else:
	connSocke.close()

收到0字节的信息,表示对方关闭了socket,我也就应该关闭socket了。

第五个知识点

处理信息时,一共也就三种方法:1、固定信息的长度;2、分割传递的信息;3、传递信息长度和信息。
在这里插入图片描述

对于第三种方式,文章还给出了建议:在这里插入图片描述因为具体没有实践过,这个知识点就先记下来。

第六个知识点

关于二进制数,要进行字节序转换。
不过文章中说,ascii码表示信息比二进制表示信息短,这一点我没理解,也就先记下来。

第七个知识点

如果对端的socket挂了(没有调用close),怎么办?
在这里插入图片描述
实际上,对端的socket挂了(比如客户进程被干掉了),这一端的socket是无法知道的。线程只会挂起,要很久才会超时。但是不要想着去关闭线程,因为关闭线程可能会把整个进程搞得很乱。

那到底怎么办?好像没有说。我猜,可能是1、设置较短的超时时间,超时,就默认对方挂了。2、就是之前说的,一次连接,只做一次交换。这样就算异常了,也只影响一次交换的数据,上层程序应该控制,进行重传或者断点续传。

第八个知识点

非阻塞方式,配合select,检查各个socket的状态,那个可以读,那个可以写,是否需要建立新的连接。
这个还挺有趣,但是我真是第一次见,所以准备下去动手试一试。

以上对我来说,是八个挺重要的知识点。希望对你们也有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值