Python socket.send () может отправить только один раз, затем socket.error: [Errno 32] Произошел сломанный канал - PullRequest
11 голосов
/ 04 июня 2011

Я новичок в сетевом программировании, поэтому, пожалуйста, прости меня, если это глупый вопрос :) Я создал 1 клиент и 1 сервер SocketServer.ThreadingMixIn на Ubuntu 10.04.2, используя Python2.7, но, похоже, я могутолько вызывайте 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()

Я запустил их в 2 отдельных терминала:

выход 1-го терминала:

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

выход 2-го терминала:

$ 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 () напрямую в 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)

, но выходы терминалов все те же :( Может кто-нибудь указатьчто я делаю не так здесь? Спасибо в adv!

Вот [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()

1 Ответ

16 голосов
/ 04 июня 2011

handle () вызывается в SocketServer.StreamRequestHandler один раз для каждого соединения . Если вы вернетесь с handle, соединение будет закрыто.

Если вы хотите, чтобы сервер обрабатывал более одной отправки / записи, вы должны выполнить цикл, пока recv () не вернет 0, указывая, что клиент закрыл соединение (или, по крайней мере, вызвал shutdown () при отправке).

Также обратите внимание, что TCP является потоковым протоколом. Вам нужно будет разработать протокол сообщений, который указывает длину или конец сообщения, и буферизовать recv до тех пор, пока у вас не будет полного сообщения. Проверьте send возвращаемое значение, чтобы убедиться, что все сообщение также отправлено, или используйте sendall.

...