Python的socket.send()只能发送一次,然后socket.error:[Errno 32]发生故障的管道

问题描述:

我是网络编程的新手,所以请原谅我,如果这是一个愚蠢的问题:) 我创建1个客户端和使用Python2.7在Ubuntu 10.04.2 1台SocketServer.ThreadingMixIn服务器,但 好像我只能在客户端调用sock.send()一次,然后我会得到一个:Python的socket.send()只能发送一次,然后socket.error:[Errno 32]发生故障的管道

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() 

我跑它们2个单独的端子:

输出第一终端的:

$ 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 

我试过两次调用sock.send() rectly在testClient.py, 为前:

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

但端子的输出仍然是相同的:( 任何人都可以请指出我究竟做错了什么? Thx in adv!

这是我想出的[溶胶]。谢谢你马克:)

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() 

手柄()被调用的SocketServer.StreamRequestHandler一次为每个连接。如果您从handle返回,则连接关闭。

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

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

+0

Thx的信息!我终于得到它的工作:) – hencrice 2011-06-05 00:17:28

+0

谢谢,我也有同样的问题。我想知道为什么这些东西没有包含在SocketServer文档中。你知道我在哪里可以找到关于SocketServer.TCPServer的详细文档吗? – 2013-11-07 19:41:27

+0

@PunitSoni,'SocketServer.py'文件非常简单。只读源代码很有意义。 – 2013-11-08 03:09:59