02_tcp_deadlock
# 这个程序我们是测试客户端和服务端在进行通信的过程中,可能会产生死锁的情况。
# 这是因为缓冲区,和TCP协议的可靠性连接导致的。
# 在程序中我们可以看到,客户端先向服务端发送数据,然后服务端就收之后再发送给客户端。
# 注意这里我们可以看到,程序设置的是不能缓冲区满就立即发送出去。
# 那么我们可以考虑一下,如果客户端需要发送的字节数比较小,那么是能够正常的通信的,
# 因为小于缓冲区的大小,不会把缓冲区填满。
# 再来考虑客户端发送数据很大的情况比如说1个G。
# 从流程上边来看,客户端的一条信息就会发送出去,而不是等着缓冲区满。
# 服务端那边也是这样的,接收到数据之后直接就发送,此时就产生问题了,因为要发送的数据是很大的,
# 客户端的数据没有发送完成,就无法调用recv接收服务端穿过来的数据,那从服务端看,服务端发送的数据
# 客户端没有接收,TCP 就判断网络不好了,就会不让服务端发送字节。同时服务端也不接受字节,就会导致
# 客户端也发送不出去。这样就导致死锁了。
# 导入模块
import argparse,socket,sys
def server(host,port,bytecount):
# 创建一个服务端的套接字。
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 设置套接字
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 套接字绑定IP,端口
sock.bind((host,port))
# 设置监听的数量为1
sock.listen(1)
# 打印出服务端的IP,端口
print("Listening at ",sock.getsockname())
while True:
# 服务端的套接字连接上客户端的套接字
sc,sockname = sock.accept()
print("Processing up to 1024 bytes at a time from",sockname)
# 定义一个变量,用来计算一共接收了多少字节。
n = 0
# 死循环,一直接收客户端发过来的字母
while True:
# 每次接收从最大客户端传过来的1024个字节,然后赋给data变量
data = sc.recv(1024)
# 约定一个结束符
if data == b'efo' or data == b'':break
# 将接收的二进制字节进行解码,然后转换成大写字母,在进行编码。
output = data.decode('ascii').upper().encode('ascii')
# 服务端发送消息给客户端。
sc.sendall(output)
# 计算接收到的字节长度
n += len(data)
print("接收的数据量为:",n)
# 强行刷新缓冲区。
sys.stdout.flush()
print('结束了')
# 回收套接字。
sc.close()
print(' Socket closed')
def client(host,port,bytecount):
# 定义一个套接字,同上边服务端。
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
bytecount = (bytecount + 15) // 16 * 16
print("bytecount",bytecount)
# 定义一个十六个字节的字符串
message = b'capitalize this'
print('Sending ',bytecount,'bytes of data,in chunks of 16 bytes')
# 连接服务端。
sock.connect((host,port))
# 定义发送数量
sent = 0
while sent <= bytecount :
# 客户端发送消息
sock.sendall(message)
sent += len(message)
print("发送了多少数据:",sent)
# 强行刷新缓冲区
sys.stdout.flush()
# 最后发送一个结束符,告诉服务端发送结束了。
sock.sendall(b'efo')
print("结束了")
# 单向的socket便称为半开放Socket。要实现半开放式,需要用到shutdown()函数。
sock.shutdown(socket.SHUT_WR)
print('Receving all the data the server sends back')
# 定义接收到的字节变量
received = 0
while True:
# 用来接收服务端传回来的消息
data = sock.recv(42)
if not received :
# 打印第一次进来,接收到的数据
print(" The firse data received says",repr(data))
if not data:
break
# 计算接收到字节数的总和。
received += len(data)
print("接收的数据量为:",received)
print('结束了')
sock.close()
if __name__ == "__main__":
# 定义一个字典
choices = {'client':client,'server':server}
parser = argparse.ArgumentParser(description = 'Get deadlocked over TCP')
parser.add_argument('role',choices = choices,help = 'which role to play')
parser.add_argument('host',help = 'interface the server listens at;'
' host the client sends to')
parser.add_argument("bytecount",type = int,nargs ='?',default = 16,
help = 'number of bytes for client to send (default 16)')
parser.add_argument('-p',metavar = "PORT",type = int,default = 1060,help = "TCP port (default 1060")
args = parser.parse_args()
function = choices[args.role]
function(args.host,args.p,args.bytecount)
02_tcp_deadlock的更多相关文章
随机推荐
- 078 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类
078 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类 本文知识点:创建类 说明:因为时间紧张,本人写博客过程中只是对知识点的关 ...
- VS2013 c++ 生成和调用DLL动态链接库(.def 方法已验证OK)
转载:https://blog.csdn.net/zhunianguo/article/details/52294339 .def 方法 创建动态库方法: 创建动态库是生成 .dll .lib 两个个 ...
- c++中 #define和const的区别
来源参考:https://blog.csdn.net/yi_ming_he/article/details/70405364 这个区别用从几个角度来说: 角度1: 就定义常量说的话: const 定 ...
- MySQL 向表中插入、删除数据
一.向表中插入一条信息 1.查看表中的数据 mysql> SELECT * FROM user; +----+---------+----------+ | id | account | pas ...
- 成理信安协会反序列化01-利用fastcoll实现md5碰撞
虽然是反序列化的题目,但主要考点在利用fastcoll实现md5碰撞. 直接上源码 <?php show_source(__FILE__); class CDUTSEC { public $va ...
- chattr 和 lsattr 命令详解
lsattr 命令 lsattr 命令用于查看文件的第二扩展文件系统属性. 语法: lsattr(选项)(参数) 选项: -E:可显示设备属性的当前值,但这个当前值是从用户设备数据库中获得的,而不是从 ...
- 《流畅的Python》 第一部分 序章 【数据模型】
流畅的Python 致Marta,用我全心全意的爱 第一部分 序幕 第一章 Python数据模型 特殊方法 定义: Python解释器碰到特殊句法时,使用特殊方法激活对象的基本操作,例如python语 ...
- JavaScript常用对象介绍
目录 对象(object) 对象的创建方式 点语法 括号表示法 内置对象 Array 数组创建方式 检测数组 转换方法 分割字符串 栈方法 队列方法 重排序方法 操作方法 位置方法 迭代方法 Stri ...
- 利用HDFS实现ElasticSearch7.2容灾方案
利用HDFS实现ElasticSearch7.2容灾方案 目录 利用HDFS实现ElasticSearch7.2容灾方案 前言 快照版本兼容 备份集群 HDFS文件系统 软件下载 JDK环境 配置系统 ...
- vue打包之后在本地运行,express搭建服务器,nginx 本地服务器运行
一.使用http-server 1.安装http-server npm install -g http-server 2.通过命令进入到dist文件夹 3.运行http-server 以上在浏览器输入 ...