我在自学Python网络,想起当年自学线程的时候,遇到了 本页所以我复制了这些脚本,更新为Python 3.1.1并运行它们。 它们完美地运行了。
然后我做了一些修改。 我的目标是做一些简单的事情。
这是服务器。
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
服务器继续运行,接收连接也很好,只有客户端崩溃了。 是什么原因造成的?
EDIT:我用下面的代码让客户端工作了。
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()
但是,我还是不明白这是怎么回事。 这不就是打开和关闭套接字一大堆次吗? 是不是应该有时间限制(你不应该在关闭一个套接字后这么快就打开它)?
你的客户端现在是正确的--你要打开套接字发送数据,接收回复,然后关闭套接字。
原先的错误是由于服务器在发送第一个响应后关闭了套接字,导致客户端在同一连接上试图发送第二个消息时收到了连接关闭消息。
但是,我还是不明白这是怎么回事。这不就是把套接字打开又关闭了一堆吗?
是的,这是可以接受的,即使不是性能最高的方式。
是不是应该有时间限制(你不应该在关闭一个socket后这么快就打开它)?
你可以尽快打开一个客户端套接字,因为每次打开套接字都会得到一个新的本地端口号,这意味着连接不会受到干扰。 在上面的服务器代码中,它会为每个进入的连接启动一个新的线程。
每一个IP连接都有4个部分(source_address,source_port,destination_address,destination_port),这个四元组(众所周知)必须为永远的连接而改变。 除了source_port之外,客户端套接字的所有内容都是固定的,所以这是操作系统为你改变的。
打开服务器套接字比较麻烦--如果你想快速打开一个新的服务器套接字,你的
server.bind(('', 2727))
以上,那么你需要阅读一下SO_REUSEADDR。