Pri*_*ata 4 python sockets python-2.7
我已经在互联网上看到并阅读了很多关于这个特定问题的内容.我正在写一个简单的聊天服务器和客户端使用python中的socket主要用于学习目的.
我在这里发现了一个问题.
这是我的服务器代码:
__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()
Run Code Online (Sandbox Code Playgroud)
这是我的客户代码:
__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()
Run Code Online (Sandbox Code Playgroud)
在客户端代码中,当我不这样做时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
Run Code Online (Sandbox Code Playgroud)
然而,当我添加该行时,问题不会发生.
现在我有两个问题:
i)我已经处理了server.py中的异常,为什么没有处理这个异常,为什么它会导致代码崩溃?如何使服务器更健壮,我缺少什么?
ii)sock.close()
与客户端中的线路相关的崩溃和异常背后的逻辑是什么?
cg9*_*909 14
i)你的try-except块没有捕获任何异常.
第一个参数except
必须是您要捕获的异常的类型.socket.errno
不是异常类,而是模块.你需要抓住socket.error
:
except socket.error, ex:
print ex
Run Code Online (Sandbox Code Playgroud)
它会"崩溃"你的代码,因为在调用堆栈中某处未处理的任何异常都会向外传播,直到它命中为止except
.如果没有处理程序,程序将被终止.
ii)当客户端在没有关闭连接的情况下终止时,RST
操作系统的TCP/IP堆栈会发送一个数据包.这大致相当于挂断电话而不说再见.Python将其转换为异常,文本为"Connection by peer".它只是意味着,因为您调用read()
Python假设您希望收到某些内容,并且当连接突然断开连接时,Python会通过引发异常来通知您.
归档时间: |
|
查看次数: |
28442 次 |
最近记录: |