我是python的新手,我正在使用socketserver
尝试创建一个服务器,将所有收到的消息从一个客户端广播到所有连接的客户端,但遇到问题。我最终得到以下错误:
在处理来自('127.0.0.1',14872)的请求期间发生异常 Traceback(最近一次调用最后一次): 在process_request_thread中输入文件“C:\ Users \ umair \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ socketserver.py”,第628行 self.finish_request(request,client_address) 在finish_request中输入文件“C:\ Users \ umair \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ socketserver.py”,第357行 self.RequestHandlerClass(request,client_address,self) 文件“C:\ Users \ umair \ AppData \ Local \ Programs \ Python \ Python35-32 \ lib \ socketserver.py”,第684行, init self.handle() 句柄中的文件“C:\ Users \ umair \ Desktop \ socketserverthread_server.py”,第52行 clients.send(数据) OSError:[WinError 10038]尝试对非套接字
的操作进行操作
我的服务器代码如下:
import socketserver
import threading
host = '127.0.0.1'
port = 6666
all_clients = []
class ThreadingHandler (socketserver.BaseRequestHandler):
def handle(self):
if (self.request) not in all_clients:
all_clients.append(self.request)
data = self.request.recv(1024)
print('%s writes: ' % str(self.client_address), end = " ")
print(data.decode())
for clients in all_clients:
clients.send(data)
class ThreadingServer (socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
myserv = ThreadingServer((host, port), ThreadingHandler)
t = threading.Thread(target = myserv.serve_forever)
t.setDaemon(True)
t.start()
print('The server is online')
客户端代码是:
import socket
host = '127.0.0.1'
port = 6666
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
data = input('You: ')
sock.send(data.encode())
received = sock.recv(1024)
print('Received: ', received.decode())
我正在运行其中两个客户端代码来测试它。来自客户端的第一条消息不会被广播,并且只是由同一客户端接收。在发送第二条消息时,我收到上述错误。这是因为我在每个周期创建一个新套接字这个问题吗?我必须在循环中创建套接字,因为如果我不这样做,那么我就无法连续发送和接收。我认为套接字对象在请求和响应后被销毁。我不知道是怎么回事。所以任何帮助都表示赞赏。谢谢。
答案 0 :(得分:0)
发送第二条消息时,我收到上述错误。是 它是由于我正在创建一个新套接字的问题 每个周期? ...我认为插座 在请求和响应之后销毁对象。我不知道 发生了什么事。
你确实知道发生了什么事;实际上,在将新套接字分配给变量时,前一个循环周期中的客户端套接字对象sock
被销毁,这导致旧套接字被关闭。但是,由于使用了socketserver
,服务器已经关闭了它的请求套接字,就在处理了一个请求之后,i。即在handle(self)
返回后。 上面提到的错误是由于遗漏了将all_clients
中的这个封闭的套接字对象考虑在内,可以这样做。 G。这样:
for clients in all_clients[:]:
if clients._closed: all_clients.remove(clients)
else: clients.send(data)
来自客户端的第一条消息不会被广播,而且只是 由同一客户收到。
消息获取广播(发送给每个客户端),只是其他客户端不打扰接收它,因为它正在input('You: ')
中等待。
我必须在循环中创建套接字,因为如果我不这样做,那么我 不能连续发送和接收。
这在某种意义上是正确的,因为你使用socketserver
,它会在每次请求后关闭连接 - 在聊天服务器的情况下不太有用。
请参阅问题“Handle multiple requests with select”以获取示例服务器,而不会遇到socketserver
等人带来的麻烦。