我正在教自己Python网络,我回想起当我自学线程时,我遇到this page,所以我复制了脚本,为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
服务器继续运行并接收连接就好了;只有客户端崩溃。造成这种情况的原因是什么?
编辑:我让客户端使用以下代码:
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()
然而,我仍然不明白发生了什么。这不仅仅是打开和关闭套接字多次?不应该有时间限制(关闭后不应该这么快就打开一个套接字)?
答案 0 :(得分:10)
您的客户端现在正确 - 您要打开套接字发送数据,接收回复然后关闭套接字。
错误原始错误是由服务器在发送第一个响应后关闭套接字引起的,该响应导致客户端在尝试在同一连接上发送第二条消息时收到连接已关闭的消息。
但是,我还是不明白 这是怎么回事。不是这个 打开和关闭插座一堆 时间?
是。如果不是最高性能的做事方式,这是可以接受的。
不应该有时间 限制(你不应该 这么快就能打开一个插座 关闭它?)
您可以随意打开客户端套接字,因为每次打开套接字时都会获得一个新的本地端口号,这意味着连接不会干扰。在上面的服务器代码中,它将为每个传入连接启动一个新线程。
每个IP连接有4个部分(source_address,source_port,destination_address,destination_port),这个四边形(因为它已知)必须改变以进行永久连接。除了source_port之外的所有内容都是针对客户端套接字修复的,这就是操作系统为您所做的更改。
打开服务器套接字更麻烦 - 如果您想快速打开新的服务器套接字,那么
server.bind(('', 2727))
然后你需要阅读SO_REUSEADDR。
答案 1 :(得分:-20)
pickle
并不是你如何序列化Python对象以便将它们发送到网上。它们是一个潜在的安全问题,因为你可以制作一个假的腌制数据包,在打开时执行arbritary代码。最好使用安全的序列化方法 - 因为有很多可用的方法,比如在整数对象上调用str()
,在另一侧调用int()
。我刚刚看到你对这个问题的评论:
@leeroy(续)我的目标是努力实现这样的事情:http://www.mcwalter.org/technology/java/httpd/tiny/index.html只在Python中
嗯,这是一个有效的实施方案:
from SimpleHTTPServer import SimpleHTTPRequestHandler as RH
from SocketServer import TCPServer
print "serving current directory at port 8000"
TCPServer(("", 8000), RH).serve_forever()