Python的socket.send()只能发送一次,然后会出现socket.error: [Errno 32] Broken pipe错误。

12

我是一个网络编程的新手,如果这个问题很愚蠢,请原谅 :) 我在Ubuntu 10.04.2上使用Python2.7创建了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)

抱歉,我还不够智能,无法理解您的要求。请提供更具体的翻译内容和格式要求。
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()
1个回答

17

SocketServer.StreamRequestHandler中的handle()会针对每个连接调用一次。如果从handle返回,连接将被关闭。

如果你想让服务器处理多个send/recv操作,你必须循环执行recv(),直到其返回0,表示客户端已关闭连接(或至少在发送方面调用了shutdown())。

还要注意TCP是一种流协议。你需要设计一种消息协议来指示消息的长度或结束,并缓冲recv直到收到完整的消息。检查send返回值以确保所有消息都已发送,或使用sendall


谢谢,我也遇到了同样的问题。我想知道为什么这些内容没有包含在SocketServer文档中。你知道在哪里可以找到关于SocketServer.TCPServer的详细文档吗? - Punit Soni
@PunitSoni,SocketServer.py文件非常简单。仅仅阅读源代码就可以了解它的运作原理。 - Mark Tolonen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接