12

私はネットワークプログラミングの初心者なので、これがばかげた質問である場合はご容赦ください:) Python2.7を使用してUbuntu 10.04.2で1つのクライアントと1つのSocketServer.ThreadingMixInサーバーを作成しましたが、sockしか呼び出せないようですクライアントで .send() を 1 回実行すると、次のようになります。

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

たとえば、testClient.pyでsock.send()を2回直接呼び出してみました。

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

しかし、端末の出力はまだ同じです:(誰かが私がここで間違っていることを指摘できますか?前もってThx!

思いついた【ソル】はこちら。ありがとうマーク:)

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

1 に答える 1

17

handle() は接続SocketServer.StreamRequestHandlerごとに 1 回呼び出されます。接続から戻った場合は閉じられます。handle

サーバーに複数の送信/受信を処理させたい場合は、recv() が 0 を返し、クライアントが接続を閉じたことを示す (または少なくとも送信時に shutdown() が呼び出される) までループする必要があります。

また、TCP はストリーミング プロトコルであることに注意してください。メッセージの長さまたは終了を示すメッセージ プロトコルを設計しrecv、完全なメッセージが得られるまでバッファリングする必要があります。send戻り値をチェックして、すべてのメッセージも送信されていることを確認するか、 を使用してsendallください。

于 2011-06-04T16:16:27.017 に答える