连接由 Python 2.7 中的 peer [errno 104] 重置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33111556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Connection reset by peer [errno 104] in Python 2.7
提问by Priyabrata
I've seen and read a lot about this particular issue on the internet. I am writing a simple chat server and client using socket in python for learning purpose mainly.
我已经在互联网上看到并阅读了很多关于这个特定问题的信息。我正在使用python中的套接字编写一个简单的聊天服务器和客户端,主要用于学习目的。
I've observed an issue here.
我在这里观察到一个问题。
Here is my server code :
这是我的服务器代码:
__author__ = 'pchakraverti'
import socket
import select
import sys
class NickSocketMap(object):
count = 0
def __init__(self, nick, client_socket):
self.nick = nick
self.client_socket = client_socket
NickSocketMap.count += 1
@staticmethod
def display_count():
print "Total number of clients is %d" % NickSocketMap.count
host = ""
port = 7575
socket_list = []
nick_list = []
cnt = 0
recv_buffer = 1024
def register_nick(nick, client_socket):
obj = NickSocketMap(nick, client_socket)
nick_list.append(obj)
def process_request(request_string, client_socket):
parts = request_string.split("|")
if parts[0] == "set_nick":
register_nick(parts[1], client_socket)
client_socket.send("nick_set")
elif parts[0] == "transmit_msg":
broadcast_message(parts[1], parts[2])
return 1
def broadcast_message(message, client_nick):
for s in nick_list:
if s.nick == client_nick:
try:
s.client_socket.send(message)
except socket.errno, ex:
print ex
break
def run_server():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.bind((host, port))
except socket.errno, ex:
print ex
sys.exit(-1)
sock.listen(10)
# add the parent socket in the list
socket_list.append(sock)
# keep the server alive
while True:
try:
read_ready, write_ready, in_error = select.select(socket_list, [], [], 0)
except select.error, ex:
print ex
continue
for s in read_ready:
# check if s is the parent socket
if s == sock:
# accept new connection and append to list
try:
con, addr = s.accept()
if con not in socket_list:
socket_list.append(con)
except socket.errno, ex:
print ex
else:
try:
# receive packet from connected client
packet = s.recv(recv_buffer)
if not packet:
socket_list.remove(s)
read_ready.remove(s)
for n in nick_list:
if n.client_socket == s:
nick_list.remove(n)
break
break
print packet
except socket.errno, ex:
print ex
continue
process_request(packet, s)
sock.close()
if __name__ == "__main__":
run_server()
and here is my client code:
这是我的客户端代码:
__author__ = 'pchakraverti'
import socket
nick = ""
host = "192.168.0.167"
port = 7575
sock = ""
def welcome():
print "Welecome to SecuChat!"
print "---------------------"
def init():
nick = raw_input("Enter your chat nickname : ")
print nick
global sock
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((host, port))
except socket.errno, ex:
print ex
sock.send("set_nick|"+nick)
#sock.close()
if __name__ == "__main__":
welcome()
init()
In the client code, when I don't do the sock.close()
, the server runs into an exception :
在客户端代码中,当我不这样做时sock.close()
,服务器会遇到异常:
Traceback (most recent call last):
File "server.py", line 102, in <module>
run_server()
File "server.py", line 84, in run_server
packet = s.recv(recv_buffer)
socket.error: [Errno 104] Connection reset by peer
how ever, when I add that line, the problem doesn't occur.
但是,当我添加该行时,问题不会发生。
Now I've two questions :
现在我有两个问题:
i) I've handled exceptions in the server.py, why is this exception not being handled and why is it crashing the code ? How can I make the server more robust and what am I missing ?
i) 我已经处理了 server.py 中的异常,为什么这个异常没有被处理,为什么它会导致代码崩溃?我怎样才能使服务器更健壮,我错过了什么?
ii) What is the logic behind this crash and exception in relation to the sock.close()
line in the client ?
ii)sock.close()
与客户端中的行相关的崩溃和异常背后的逻辑是什么?
采纳答案by cg909
i) Your try-except block doesn't catch any exceptions.
i) 您的 try-except 块不会捕获任何异常。
The first argument to except
must be the type of the exception you want to catch. socket.errno
is not an exception class but a module. You need to catch socket.error
:
的第一个参数except
必须是您要捕获的异常的类型。socket.errno
不是异常类而是模块。你需要抓住socket.error
:
except socket.error, ex:
print ex
It "crashes" your code because any exception that isn't handled somewhere in the call stack propagates outwards until it hits an except
. If there is no handler the program is terminated.
它使您的代码“崩溃”,因为调用堆栈中某处未处理的任何异常都会向外传播,直到遇到except
. 如果没有处理程序,程序将终止。
ii) When the client terminates without closing the connection, a RST
packet is sent by the TCP/IP stack of your OS. This is roughly the equivalent of hanging up a phone without saying goodbye. Python converts this into an exception with the text "Connection reset by peer". It simply means that since you called read()
Python assumed you expect to receive something and when the connection suddenly disconnected, Python informs you of this by raising the exception.
ii) 当客户端在没有关闭连接的情况下终止时RST
,您的操作系统的 TCP/IP 堆栈会发送一个数据包。这大致相当于挂断电话而不说再见。Python 将其转换为带有文本“Connection reset by peer”的异常。这只是意味着,由于您调用read()
Python 时假设您希望收到某些东西,而当连接突然断开时,Python 会通过引发异常来通知您这一点。