【发布时间】:2010-12-01 04:01:15
【问题描述】:
我正在自学 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()
但是,我仍然不明白发生了什么。这不只是多次打开和关闭套接字吗?不应该有时间限制吗(你不应该在关闭套接字后这么快就打开它)?
【问题讨论】:
-
代码中有一些明显的错误,似乎假设一侧的 1 个 send 调用导致另一侧的 1 个 recv 调用,这可能不是真的,TCP 是流协议,它不是面向消息或数据包。但不确定这与错误消息有何关系。
-
@leeroy 我显然对此有点陌生,所以我完全愿意接受批评。您似乎在建议我不应该使用 TCP,因为它是流而不是面向数据包的;但是不能将数据包简单地表示为非常短的数据流吗?我知道它不是应该使用的,但这只是为了测试;显然,我打算推送比单个整数更多的数据。
-
@leeroy(续)我的目标是努力实现这样的东西:mcwalter.org/technology/java/httpd/tiny/index.html 仅在 Python 中。
-
您可以在 tcp 之上构建自己的“数据包”/记录。例如发送 1 个数字后跟换行符。然后接收端可以读取行。 1 行 = 你会知道你已经阅读了 1 个数字。
-
您的服务器只读取一个请求并发送一个响应。因此,要么从您的客户端删除循环,要么将一个循环添加到服务器处理程序中。您还需要一些适当的异常和流结束处理,以及服务器端的读取超时。
标签: python networking