Jia*_*Liu 5 python sockets networking network-programming tcp
我已经了解了 tcp 中两个臭名昭著的错误之间的区别:
[Errno 54] Connection reset by peer[Errno 32] Broken pipe这两个错误都是tcp连接的一侧因未知原因关闭,另一侧仍在与其通信。
write东西,Broken pipe被扔read东西,Connection reset by peer被扔我能够Broken pipe使用下面的 Python 代码进行重现。
# tcp_server.py
def handler(client_sock, addr):
try:
print('new client from %s:%s' % addr)
finally:
client_sock.close() # close current connection directly
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 5500))
sock.listen(5)
while 1:
client_sock, addr = sock.accept()
handler(client_sock, addr)
Run Code Online (Sandbox Code Playgroud)
至于客户,
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('', 5500))
>>> sock.send('a')
1
>>> sock.send('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 32] Broken pipe
Run Code Online (Sandbox Code Playgroud)
当客户端首先send,一个RST数据包从服务器发送到客户端,从这一刻开始,send将始终抛出Broken pipe。
以上的一切都在我的理解之内。但是,当客户端从服务器读取时,它总是返回空字符串而不是抛出Connection reset by peer
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('', 5500))
>>> sock.recv(1024)
''
>>> sock.recv(1024)
''
>>> sock.recv(1024)
''
>>> sock.recv(1024)
Run Code Online (Sandbox Code Playgroud)
我对此感到困惑,或者一般如何重现Connection reset by peer?
您可以将套接字“linger”选项设置为 0 并关闭套接字以发送重置。更新您的服务器
import socket
import struct
import time
# tcp_server.py
def handler(client_sock, addr):
try:
print('new client from %s:%s' % addr)
time.sleep(1)
finally:
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
struct.pack('ii', 1, 0))
client_sock.close() # close current connection directly
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 5500))
sock.listen(5)
while 1:
client_sock, addr = sock.accept()
handler(client_sock, addr)
Run Code Online (Sandbox Code Playgroud)
并运行这个客户端
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('', 5500))
print(sock.recv(1024))
Run Code Online (Sandbox Code Playgroud)
我有
Traceback (most recent call last):
File "tcpclient.py", line 5, in <module>
print(sock.recv(1024))
ConnectionResetError: [Errno 104] Connection reset by peer
Run Code Online (Sandbox Code Playgroud)