我正在自学Python网络,我回想起当我自学线程时,我遇到了这个页面,所以我复制了脚本,为Python 3.1.1更新了它们并运行它们.他们工作得很好.
然后我做了一些修改.我的目标是做一些简单的事情:
客户端挑选一个整数并将其发送到服务器.
服务器接收pickle整数,取消它,将其加倍,然后将其pickle并将其发送回客户端.
客户端接收pickle(和doubled)整数,取消它并输出它.
这是服务器:
import pickle import socket import threading class ClientThread(threading.Thread): def __init__(self, channel, details): self.channel = channel self.details = details threading.Thread.__init__ ( self ) def run(self): print('Received connection:', self.details[0]) request = self.channel.recv(1024) response = pickle.dumps(pickle.loads(request) * 2) self.channel.send(response) self.channel.close() print('Closed connection:', self.details [ 0 ]) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(('', 2727)) server.listen(5) while True: channel, details = server.accept() ClientThread(channel, details).start()
这是客户:
import pickle import socket import threading class ConnectionThread(threading.Thread): def run(self): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('localhost', 2727)) for x in range(10): client.send(pickle.dumps(x)) print('Sent:',str(x)) print('Received:',repr(pickle.loads(client.recv(1024)))) client.close() for x in range(5): ConnectionThread().start()
服务器运行正常,当我运行客户端时,它成功连接并开始发送整数并按预期接收它们.然而,它很快就被排除在外:
Exception in thread Thread-2: Traceback (most recent call last): File "C:\Python30\lib\threading.py", line 507, in _bootstrap_inner self.run() File "C:\Users\Imagist\Desktop\server\client.py", line 13, in run print('Received:',repr(pickle.loads(client.recv(1024)))) socket.error: [Errno 10053] An established connection was aborted by the softwar e in your host machine
服务器继续运行并接收连接就好了; 只有客户端崩溃.是什么导致了这个?
编辑:我让客户端使用以下代码:
import pickle import socket import threading class ConnectionThread(threading.Thread): def run(self): for x in range(10): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(('localhost', 2727)) client.send(pickle.dumps(x)) print('Sent:',str(x)) print('Received:',repr(pickle.loads(client.recv(1024)))) client.close() for x in range(5): ConnectionThread().start()
但是,我仍然不明白发生了什么.这不仅仅是打开和关闭套接字多次?不应该有时间限制(你不应该在关闭后这么快打开一个插座)?
您的客户端现在是正确的 - 您要打开套接字发送数据,接收回复然后关闭套接字.
错误原始错误是由服务器在发送第一个响应后关闭套接字引起的,该响应导致客户端在尝试在同一连接上发送第二条消息时收到连接已关闭的消息.
但是,我仍然不明白发生了什么.这不仅仅是打开和关闭套接字多次?
是.如果不是最高性能的做事方式,这是可以接受的.
不应该有时间限制(你不应该在关闭后这么快打开一个插座)?
您可以随意打开客户端套接字,因为每次打开套接字时都会获得一个新的本地端口号,这意味着连接不会干扰.在上面的服务器代码中,它将为每个传入连接启动一个新线程.
每个IP连接有4个部分(source_address,source_port,destination_address,destination_port),这个四边形(因为它已知)必须改变以进行永久连接.除了source_port之外的所有内容都是针对客户端套接字修复的,这就是操作系统为您所做的更改.
打开服务器套接字更麻烦 - 如果你想快速打开一个新的服务器套接字,你的
server.bind(('', 2727))
在上面你需要阅读SO_REUSEADDR.