我有简单的python服务器和客户端。
服务器:
import SocketServer
import threading
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print str(self.client_address[0]) + " wrote: "
print self.data
self.request.send(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 3288
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
客户端:
import socket
import sys
from time import sleep
HOST, PORT = "localhost", 3288
data = "hello"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
sock.send(data + "\n")
received = sock.recv(1024)
sleep(10)
sock.send(data + "\n")
received = sock.recv(1024)
sleep(10)
sock.send(data + "\n")
received = sock.recv(1024)
finally:
sock.close()
以下是我得到的输出:
服务器:
>python server.py
127.0.0.1 wrote:
hello
客户端:
>python client.py
Traceback (most recent call last):
File "client.py", line 18, in <module>
received = sock.recv(1024)
socket.error: [Errno 10053] An established connection was aborted by the software in your host machine
我也在linux机器上试过它。服务器只接收一条消息,然后我在第二条消息的recv语句上收到错误。我刚刚开始在python上学习网络,但我认为服务器出于某种原因关闭了套接字。我该如何纠正?
答案 0 :(得分:22)
为每个连接创建一个MyTcpHandler
对象,并调用handle
来处理客户端。当handle
返回时,连接将关闭,因此您必须在handle
方法中处理来自客户端的完整通信:
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
while 1:
self.data = self.request.recv(1024)
if not self.data:
break
self.data = self.data.strip()
print str(self.client_address[0]) + " wrote: "
print self.data
self.request.send(self.data.upper())
注意:recv
在客户端关闭连接时返回''
,因此我在.strip()
之后移动了recv
,因此客户端仅发送错误警报白色空间。
答案 1 :(得分:1)
我首先承认,自从我上次使用SocketServer
以来已经有好几年了,所以可能会有更多惯用的方法来解决您的问题。
请注意,您的客户端会打开一个连接并发送三组数据并接收三组数据。 (希望在套接字上调用receive()
后,TCP堆栈将发送缓冲数据。)
从SocketServer
回调机制调用服务器时,服务器期望从头到尾完全处理客户端连接。您当前的类会执行一些IO,然后退出。您只需要扩展服务器回调以执行更多操作:
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print str(self.client_address[0]) + " wrote: "
print self.data
self.request.send(self.data.upper())
foo = self.request.recv(1024).strip()
self.request.send(foo.lower())
bar = self.request.recv(1024).strip()
self.request.send("goodbye " + bar)
答案 2 :(得分:1)
这里遇到类似的问题error: [Errno 10053]
我也尝试了同样的事情并得到了同样的错误。
如果有这样的简单代码来演示此错误:
import socket
host = 'localhost'
port = 5001
size = 102400
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
for msg in ['Hello, world','Test','anything goes here']:
s.send(msg)
data = s.recv(size)
print 'Received:', data
s.close()
如果你创建一个套接字对象,它可以从服务器发送和回显,以查看接收器的数量,如果你改变它,比如说1024到102400(在这段代码中); 这意味着套接字不应该关闭,但在我的Windows操作系统中,服务器端一直在监听和打印客户端发送的任何数据,但在客户端,您会收到此错误;
但是,如果客户端只能连接一次并且只发送和接收一次,那就是它的设计方式。尝试这种方法没有任何错误:
for msg in ['Hello, world','Test','anything goes here']:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send(msg)
data = s.recv(size)
s.close()
print 'Received:', data
我不确定一个套接字对象是否只能工作一次以发送和接收数据。
<强>更新强> 我认为问题是每个客户端套接字按照固定的buffersize接收数据的容量; 这就是为什么上面的第二个代码片段工作,从而在服务器上创建新的客户端连接套接字。但是那样很多套接字都会被用完。
相反,以下代码通过检查已用完的大小的amt来解决该问题。如果它超过给定的数量,它会在客户端创建一个新套接字,但要确保发送消息;实际上问题出在服务器代码上,但修复了它。
size = 10
这是对代码的快速尝试。我相信你会理解并优化它!
客户代码:
messag = ['Hello, world', 'Test', 'anything goes here']
def client_to_server(messag,host,port,size):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
countmsg = 0
restmsg = ''
for msg in messag:
strl = tmsg = msg
if len(restmsg):
tmsg = restmsg + ' ' + msg
countmsg = len(tmsg)
if countmsg <= size:
pass
else:
restmsg = tmsg[size:]
tmsg = tmsg[:size]
#s.close()
countmsg = len(tmsg)
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.connect((host, port))
print 'Sending to server msg {}'.format(tmsg)
s.send(tmsg)
# s.settimeout(1)
try:
data = s.recv(size)
print 'Received:', data
if strl == data:
print strl,data
countmsg = 0
restmsg = ''
except (socket.error), e:
print e.args,e.message
s.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.close()
if restmsg:
client_to_server([restmsg],host,port,size)
return
client_to_server(messag,host,port,size)
服务器代码:
size = 1024 #This has to be bigger than client buf size!
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(backlog)
while True:
#this is what accepts and creates a P2P dedicated client socket per socket
client, address = s.accept()
try:
data = client.recv(size)
while data or 0:
print "Client sent {} | Server sending data to client address {}".format(data, address)
client.send(data)
data = client.recv(size)
else: client.close()
except (socket.error), e:
client.close()
print e.args, e.message
试一试。这使用相同的套接字。