我们想要实现一个简单的 Python 点对点聊天程序,让服务器和客户端可以相互发送消息。但是,在服务器端发送消息时,我们遇到了一个错误:
File "server.py", line 40, in <module>
newSocket.send('\r<Server>: ' + msg)
socket.error: [Errno 32] Broken pipe
2、解决方案
问题的原因是服务器端在发送消息时,客户端已经断开了连接。为了解决这个问题,我们可以使用 accept()
方法来检查是否有新的客户端连接,然后再发送消息。
以下是修改后的服务器端代码:
import socket
import os
import select
import sys
def prompt():
sys.stdout.write('Server : ')
sys.stdout.flush()
try:
newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
print 'socket Error'
sys.exit(1)
newSocket.bind(('127.0.0.1', 8000))
newSocket.listen(5)
input_list = [newSocket, sys.stdin]
print 'Chat Program'
prompt()
while True:
inputready, outputready, exceptready = select.select(input_list,[],[])
for sock in inputready:
if sock == newSocket:
(client, (ip, port)) = newSocket.accept()
input_list.append(client)
elif sock == sys.stdin:
msg = sys.stdin.readline()
for c in input_list:
if c != newSocket and c != sys.stdin:
c.send('\r<Server>: ' + msg)
prompt()
else:
data = sock.recv(2048)
if data:
sys.stdout.write(data)
newSocket.close()
在新的代码中,我们首先使用 accept()
方法来检查是否有新的客户端连接。如果发现有新的客户端连接,我们就将该客户端加入到 input_list
中。然后,我们在 input_list
中遍历所有客户端,并向每个客户端发送消息。这样,我们就避免了在客户端断开连接后向其发送消息,从而解决了错误。
以下是修改后的客户端端代码:
import socket
import os
import select
import sys
def prompt():
sys.stdout.write('Client ')
sys.stdout.flush()
try:
newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
print 'socket Error'
sys.exit(1)
newSocket.connect(('127.0.0.1', 8000))
print 'Connected to remote host. Start sending messages'
prompt()
while 1:
socket_list = [sys.stdin, newSocket]
read_sockets, write_sockets, error_sockets = select.select(socket_list, [], [])
for sock in read_sockets:
if sock == newSocket:
data = sock.recv(4096)
if not data:
print '\nDisconnected from chat server'
sys.exit()
else:
sys.stdout.write(data)
prompt()
else:
msg = sys.stdin.readline()
newSocket.send('\r<Client>: ' + msg)
prompt()
在新的代码中,我们增加了对 newSocket
的检查。如果 newSocket
已断开连接,我们就退出程序。这样,我们就确保了只向已连接的客户端发送消息。
通过这两个修改,我们就解决了 socket.error: [Errno 32] Broken pipe
的错误,并成功实现了非阻塞点对点聊天程序。