问题 Python socket.send()只能发送一次,然后socket.error:[Errno 32]发生了断管


我是网络编程的新手,所以请原谅我,如果这是一个愚蠢的问题:) 我使用Python2.7在Ubuntu 10.04.2上创建了1个客户端和1个SocketServer.ThreadingMixIn服务器,但是 好像我只能在客户端调用sock.send()一次,然后我会得到一个:

Traceback (most recent call last):
  File "testClient1.py", line 33, in <module>
    sock.send('c1:{0}'.format(n))   
socket.error: [Errno 32] Broken pipe

这是我写的代码:

testClient1.py:

#! /usr/bin/python2.7
# -*- coding: UTF-8 -*-
import sys,socket,time,threading
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    sock.connect(('localhost',20000))
except socket.error:
    print('connection error')
    sys.exit(0)
n=0
while n<=1000:
    sock.send('c1:{0}'.format(n))   
    result=sock.recv(1024)
    print(result)
    n+=1
    time.sleep(1)

testServer.py:

#! /usr/bin/python2.7
# -*- coding: UTF-8 -*-
import threading,SocketServer,time

class requestHandler(SocketServer.StreamRequestHandler):
    #currentUserLogin={} #{clientArr:accountName}
    def handle(self):
        requestForUpdate=self.rfile.read(4)
        print(requestForUpdate)
        self.wfile.write('server reply:{0}'.format(requestForUpdate))

class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

if __name__ == '__main__':

    server=broadcastServer(('localhost',20000),requestHandler)
    t = threading.Thread(target=server.serve_forever)
    t.daemon=True
    t.start()
    print('server start')
    n=0
    while n<=60:
        print(n)
        n+=1
        time.sleep(1)
    server.socket.close()

我在两个独立的终端上运行它们:

第一终端输出:

$ python2.7 testServer.py
server start
0
1
2
3
4
c1:0
5
6
7
8
9
10
11
...

第二终端输出:

$ python2.7 testClient1.py
server reply:c1:0

Traceback (most recent call last):
  File "testClient1.py", line 33, in <module>
    sock.send('c1:{0}'.format(n))   
socket.error: [Errno 32] Broken pipe

我试着直接在testClient.py中调用sock.send()两次, 对于前:

while n<=1000:
        sock.send('c1:{0}'.format(n))
        sock.send('12333')    
        result=sock.recv(1024)
        print(result)
        n+=1
        time.sleep(1)

但终端的输出仍然是相同的:( 任何人都可以指出我在这里做错了什么? 谢谢!

这是我提出的[Sol]。谢谢马克:)

testClient1.py:

import sys,socket,time
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    sock.connect(('localhost',20000))
except socket.error:
    print('connection error')
    sys.exit(0)
n=0
while n<=10:    #connect once
    sock.send('c1:{0}'.format(n))
    result=sock.recv(1024)
    print(result)    
    n+=1
    time.sleep(1)
sock.close()

#once you close a socket, you'll need to initialize it again to another socket obj if you want to retransmit
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
    sock.connect(('localhost',20000))
except socket.error:
    print('connection error')
    sys.exit(0)
n=0
while n<=10:    #connect once
    sock.send('c3:{0}'.format(n))
    result=sock.recv(1024)
    print(result)    
    n+=1
    time.sleep(1)
sock.close()

testServer.py:

import threading,SocketServer,time

class requestHandler(SocketServer.StreamRequestHandler):
    #currentUserLogin={} #{clientArr:accountName}
    def handle(self):
        requestForUpdate=self.request.recv(1024)
        print(self.client_address)
        while requestForUpdate!='':           
            print(requestForUpdate)
            self.wfile.write('server reply:{0}'.format(requestForUpdate))
            requestForUpdate=self.request.recv(1024)
        print('client disconnect')

class broadcastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

if __name__ == '__main__':

    server=broadcastServer(('localhost',20000),requestHandler)
    t = threading.Thread(target=server.serve_forever)
    t.daemon=True
    t.start()
    print('server start')
    n=0
    while n<=60:
        print(n)
        n+=1
        time.sleep(1)
    server.socket.close()

9393
2018-06-04 15:21


起源



答案:


handle()在。中调用 SocketServer.StreamRequestHandler 每次一次 连接。如果你从 handle 连接已关闭。

如果您希望服务器处理多个send / recv,则必须循环直到recv()返回0,表示客户端关闭了连接(或者至少在发送时调用了shutdown())。

另请注意,TCP是一种流媒体协议。您需要设计一个消息协议,指示消息的长度或结束,以及缓冲区 recv 直到你有一个完整的消息。检查 send 返回值以确保发送所有消息,或使用 sendall


16
2018-06-04 16:16



感谢!!我终于搞定了:) - hencrice
谢谢,我也有同样的问题。我想知道为什么这些东西不包含在SocketServer文档中。你知道在哪里可以找到关于SocketServer.TCPServer的详细文档吗? - Punit Soni
@PunitSoni, SocketServer.py 文件很简单。阅读源代码是有益的。 - Mark Tolonen


答案:


handle()在。中调用 SocketServer.StreamRequestHandler 每次一次 连接。如果你从 handle 连接已关闭。

如果您希望服务器处理多个send / recv,则必须循环直到recv()返回0,表示客户端关闭了连接(或者至少在发送时调用了shutdown())。

另请注意,TCP是一种流媒体协议。您需要设计一个消息协议,指示消息的长度或结束,以及缓冲区 recv 直到你有一个完整的消息。检查 send 返回值以确保发送所有消息,或使用 sendall


16
2018-06-04 16:16



感谢!!我终于搞定了:) - hencrice
谢谢,我也有同样的问题。我想知道为什么这些东西不包含在SocketServer文档中。你知道在哪里可以找到关于SocketServer.TCPServer的详细文档吗? - Punit Soni
@PunitSoni, SocketServer.py 文件很简单。阅读源代码是有益的。 - Mark Tolonen