Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python sendall未引发连接关闭错误_Python_Sockets_Network Programming - Fatal编程技术网

python sendall未引发连接关闭错误

python sendall未引发连接关闭错误,python,sockets,network-programming,Python,Sockets,Network Programming,我有以下代码,在linux/mac、远程和本地计算机上使用python2.7和python3.5进行了测试: import socket import time s = socket.socket() s.connect(("127.0.0.1", 8080)) s.sendall(b'first') time.sleep(20) s.sendall(b'should fail') 另一方面,我有一个运行netcat-l-p8080的服务器 我一看到第一个,就杀死netcat命令 然而,s.

我有以下代码,在linux/mac、远程和本地计算机上使用python2.7和python3.5进行了测试:

import socket
import time

s = socket.socket()
s.connect(("127.0.0.1", 8080))
s.sendall(b'first')
time.sleep(20)
s.sendall(b'should fail')
另一方面,我有一个运行netcat-l-p8080的服务器

我一看到第一个,就杀死netcat命令

然而,s.sendall没有引发任何异常,为什么会这样

编辑:请注意,再次执行s.sendall会引发异常

import socket
import time

s = socket.socket()
s.connect(("127.0.0.1", 8080))
s.sendall(b'first')
time.sleep(20)
s.sendall(b'should fail')
s.sendall(b'now it really fails')

因为python代码表示的客户端还不知道服务器的套接字已关闭并消失。将TCP连接视为两个独立的通道:每个方向一个。TCP协议允许每一方在自己选择的时间关闭其连接的发送端。TCP无法向另一方表明,将来向另一个方向发送的数据将不被接受

更详细地说。。。TCP会话的普通终止涉及每一方发送一个设置了FIN标志的数据包。这表示发送FIN的对等方将不再发送任何数据。它并不表示FIN数据包的接收器可能不再发送任何数据

因此,这里发生的是,当您杀死netcat时,一个FIN数据包从服务器端发送到客户端,并由网络堆栈代表客户端确认。这将关闭套接字的服务器=>客户端方向。但是,据客户端所知,client=>server方向仍然可用。稍后,当您的客户机尝试发送数据时,将发送包含该数据的数据包。现在,服务器端的网络堆栈立即响应,通过发送RST数据包通知客户端服务器已不在那里。但是,您的sendall函数调用在收到时已很长时间完成

因此,如果您的客户机再睡一秒钟,或者实际上只睡一秒钟的一小部分,然后尝试另一次发送,那么随后的发送将引发异常

创建整个会话的数据包捕获并使用wireshark进行研究可能会很有帮助。在调用python代码之前在另一个窗口中运行此命令,然后使用Ctrl-C终止:

sudo tcpdump -i lo -w /tmp/f.pcap port 8080

您还可以使用wireshark捕获它,将同一端口8080指定为捕获筛选器,或将tcp.port==8080指定为显示筛选器。

因为python代码所代表的客户端还不知道服务器的套接字已关闭并消失。将TCP连接视为两个独立的通道:每个方向一个。TCP协议允许每一方在自己选择的时间关闭其连接的发送端。TCP无法向另一方表明,将来向另一个方向发送的数据将不被接受

更详细地说。。。TCP会话的普通终止涉及每一方发送一个设置了FIN标志的数据包。这表示发送FIN的对等方将不再发送任何数据。它并不表示FIN数据包的接收器可能不再发送任何数据

因此,这里发生的是,当您杀死netcat时,一个FIN数据包从服务器端发送到客户端,并由网络堆栈代表客户端确认。这将关闭套接字的服务器=>客户端方向。但是,据客户端所知,client=>server方向仍然可用。稍后,当您的客户机尝试发送数据时,将发送包含该数据的数据包。现在,服务器端的网络堆栈立即响应,通过发送RST数据包通知客户端服务器已不在那里。但是,您的sendall函数调用在收到时已很长时间完成

因此,如果您的客户机再睡一秒钟,或者实际上只睡一秒钟的一小部分,然后尝试另一次发送,那么随后的发送将引发异常

创建整个会话的数据包捕获并使用wireshark进行研究可能会很有帮助。在调用python代码之前在另一个窗口中运行此命令,然后使用Ctrl-C终止:

sudo tcpdump -i lo -w /tmp/f.pcap port 8080

您也可以使用wireshark来捕获它,将同一端口8080指定为捕获筛选器,或将tcp.port==8080指定为显示筛选器。

hmmm是如果我有第三次睡眠,则发送所有这一次失败,管道断开,这意味着如果我想测试连接是否关闭,我需要至少打两次sendall或send?第二次应该可以,没有任何睡眠或运气,对吗?因为电话被阻塞了,对吧?不一定不睡觉。调用是阻塞的-但只有在数据被复制到内核网络缓冲区之前,当sendall调用返回时,它仍然没有完成RST数据包的发送和接收。有几种方法可以检测另一侧是否已关闭。一种是将套接字作为读取FD之一调用select,其思想是,当另一端关闭时,select将告诉您套接字实际上变得可读,在该点之后调用read/recv将返回套接字上的文件结尾。如果我
有第三次睡眠然后发送这一次由于管道破裂而失败,所以这意味着如果我想测试连接是否关闭,我需要至少调用两次发送或发送?第二次应该可以,没有任何睡眠或运气,对吗?因为电话被阻塞了,对吧?不一定不睡觉。调用是阻塞的-但只有在数据被复制到内核网络缓冲区之前,当sendall调用返回时,它仍然没有完成RST数据包的发送和接收。有几种方法可以检测另一侧是否已关闭。一种是将套接字作为读取FD之一调用select,其思想是,当另一端关闭时,select将告诉您套接字实际上变得可读,在该点之后调用read/recv将返回套接字上的文件结尾。