1. 首先来看一下recv函数的各个参数

函数原型:int recv( SOCKET s, char *buf, int  len, int flags)

功能:不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

参数一:指定接收端套接字描述符;

参数二:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

参数三:指明buf的长度;

参数四 :一般置为0。

同步Socket的recv函数的执行流程:当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,

如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR;

如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,直到协议把数据接收完毕;

当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数;

如果recv在copy时出错,那么它返回SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。

2.“坑”在哪里,在返回值上,在阻塞与非阻塞上

要知道,recv函数是阻塞的,也就是会一直等待服务端发送来的数据包。如果没有数据包到来,就一直会等待。

这就直接导致了我用python写服务端的时候出现的一个解决了很久的错误,我的代码很简单,就是python服务端循环调用recv函数接收从客户端发来的一个文件,如下:

    data = connection.recv(1024)total_data += datanum = len(data)# 我一开始以为如果没有数据了,读出来的data长度为0,len(data)==0,从而导致卡在while循环中while len(data) > 0:data = connection.recv(1024)num += len(data)total_data += data

而实际上只有当recv函数在等待协议接收数据时网络中断了,它才返回0,这就导致我在服务端一直没有反应,等待了很久之后,我将客户端关闭之后,出现了结果,其实就是这时候 len(data)=0 了。

3. 解决方法有哪些呢?

后来搜集资料才发现recv本身是一个阻塞的,所以可以通过以下两种方法,将recv设置为非阻塞:

1. socket.setblocking(0)

2. 使用 socket.MSG_DONTWAIT

注意将套接字设置为非阻塞时,可能会报一个错:

WinError 10035 无法立即完成一个非阻止性套接字操作

这个错误就是,recv不阻塞了。在 send 数据出去后,服务端还来没来得急返回数据,客户端已经跑到了recv这里,而又不阻塞,所以抛出了一个异常。

要解决这个问题,你需要在每个 recv 函数前加一句 time.sleep(2),

其实还可以通过设置 socket.settimeout(5)  即超时时间来改变recv的阻塞状态,间接地将阻塞状态变为非阻塞状态。当然,你得确保你的超时时间足够使recv函数接收完所有的数据才行。

我就是通过设置超时时间解决了这个问题,你如果也有同样的问题的话,你也可以试试。

但是设置超时在实际情况中是一个不是很推荐的方法,后来在对socket原理的了解上更改了代码,解决了这个问题,服务端把设置超时去掉,然后在Android即Java客户端发送完所有的数据之后,加上如下语句:

this.socket.shutdownOutput();

就可以解决这个服务端阻塞的问题。

最后遇到问题,一定要去多看看别人是怎么解决的,多和有经验的人交流交流,不然时间就在纠结苦恼中溜走了。当然,自己首先要进行独立思考,并将问题一步步放小,找到真正的问题症结所在,再去下手。最后如果问题得到解决了,记得分享一下以供更多人参考哦~

盘点python socket 中recv函数的坑相关推荐

  1. python socket模块recv函数_python socket 函数 模块

    欢迎指正和留言讨论哦 import socket socket()函数 1,语法格式 socket.socket([family[, type[, proto]]]) family: 套接字家族可以使 ...

  2. [转载] python 列表List中index函数的坑

    参考链接: Python列表list sort() python 列表List中index函数的坑 例如 a = [1, 2, 1] 如果使用 a.index(1), 输出的只是列表中第一个出现的 1 ...

  3. Socket中send()函数和recv()函数详解

    目录 1.send函数 2.recv函数 关于socket的send和recv的超时设置 1.send函数 int send( SOCKET s, const char FAR *buf, int l ...

  4. Socket中send()函数和rece()函数详解

    1.send函数 int send (SOCKET s, const char FAR *buf. int len,int flags); 不论是客户还是服务器应用程序都是用send函数来向TCP连接 ...

  5. Python 字典中get() 函数

    Python 字典中get() 函数返回指定键的值. 语法:value = dict.get(key, default=None) 参数 key – 字典中要查找的键. default – 如果指定键 ...

  6. python中可以使用变量来引用函数吗_如何在python语言中使用函数变量并调用函数...

    在python语言中,除了常规变量之外,还有函数变量.把函数本身赋值给变量,这个变量为函数变量. 工具/原料 python pycharm 截图工具 WPS 方法/步骤 1 在已新建的python文件 ...

  7. qt5调用python脚本 两次失败_Qt5调用Python脚本中的函数

    我有一个简单的Qt5项目,有一个按钮和一个文本字段,我也在项目中创建了一个py文件来检查如何从Qt调用python文件中的函数.在 虽然现在我卡住了:我有我的测试cpp.h和测试cpp.cpp,其中我 ...

  8. Python pandas 中loc函数的意思及用法,及跟iloc的区别

    Python pandas 中loc函数的意思及用法,及跟iloc的区别 loc和iloc的意思 loc和iloc的区别及用法展示 参考文献 loc和iloc的意思 首先,loc是location的意 ...

  9. python loc iloc,Python pandas loc用法与iloc区别 聊聊Python pandas 中loc函数的使用,及跟iloc的区别说明...

    想了解聊聊Python pandas 中loc函数的使用,及跟iloc的区别说明的相关内容吗,Rainpages在本文为您仔细讲解Python pandas loc用法与iloc区别的相关知识和一些C ...

  10. Python程序中各函数间调用关系分析与可视化

    中国大学MOOC"Python程序设计基础"免费学习地址 2020年秋季学期Python教材推荐与选用参考 推荐图书: <Python程序设计(第3版)>,(ISBN: ...

最新文章

  1. 通过正则把文本里的链接加上a标签
  2. Spring cloud系列之Zuul配置项中sensitiveHeaders和ignoredHeaders
  3. c语言 overflow_C语言和其他语言的不得不说的差别!
  4. 最新!兰州大学发布对上海市的新冠肺炎疫情预测!
  5. IE浏览器网页无法缩放怎么办 解决IE浏览器网页无法缩放的方法
  6. 桥接模式(Bridge) 1
  7. Dive into BERT:语言模型与知识
  8. linux 版本信息 64位,Centos查看版本信息
  9. DelimiterBasedFrameDecoder 自定义分隔符解码器,解决 TCP 粘包
  10. NLP特征工程(待完善细节)
  11. ISO19000-2000标准(转载)
  12. 免费机器视觉视频教程halcon-百度网盘
  13. 3种常见软件项目工作量评估方法简述
  14. 哲学家名篇粤语诵读文2019年5月1日
  15. 谷歌神经网络机器翻译NMT:人人可利用TensorFlow快速建立翻译模型
  16. 阿拉伯数字小写金额转换成中文大写金额C程序说明
  17. HTTPS之SNI介绍与Nginx多域名支持
  18. macbook 打开以后没有声音,重启以后又好了的解决方法
  19. shiro-反序列化漏洞
  20. MySQL学习总结(一)DB、DMBS、SQL的含义/MySQL语法规范

热门文章

  1. apk反编译 (com.googlecode.d2j.DexException: not support version问题解决)
  2. AutoCAD二次开发_从入门到放弃
  3. 计算机桌面通过网络在拼接屏上显示,一种多个拼接屏实时同步显示方法与流程...
  4. 腾讯手机管家(android2.3),腾讯手机管家3.4 Android发布_软件资讯软件快报-中关村在线...
  5. amaze UI的使用
  6. 全球十大黑客(第一让你不敢想象)
  7. android gradle教程,Android Gradle入门
  8. 电气、电子电路符号与表示方法
  9. 21天通关python 磁力_利用python爬取天天看美剧磁力链接
  10. ant design pro 异步请求后台接口