1

私はPythonでソケットに初めて取り組んでいます。複数のクライアント ソケットを同じサーバー ソケットに接続する必要があります。

これを行うには、次のコードを使用しました。

import socket
import time
import random

from threading import Thread
import thread
import subprocess, signal, os

class ServerObject:
    def __init__(self, port):
        self.socket = ''
        self.host = ''
        self.port = port
        self.conn = ''
        self.data = ''

        print "Server port is: ", self.port

        def openSocketConnectionAsServer(self):
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind((self.host, self.port))
            self.socket.listen(5)
            self.conn, addr = self.socket.accept()
            print 'Server Connected by', addr

        def getData(self):
            return self.data

        def getHost(self):
            return self.host

        def getPort(self):
            return self.port

        def sendMessage(self, message):
            try :
                self.conn.sendall(message)
            except socket.error:
                print 'Server Send failed'
                sys.exit()

        def receiveMessageFromClient(self):
            while 1:
                reply = self.conn.recv(4096)
                if not self.data: break
                return reply

        def receiveMessageFromServer(self):
            reply = self.socket.recv(4096)
            return reply

        def closeConnectionAsServer(self):
            self.socket.shutdown(1)
            self.socket.close()
            del self.socket

class ClientObject:    
    def __init__(self):
        self.data = str(random.choice('abcdefghil'))
        print "Client Data Random: ", self.data
        self.host = 'localhost'
        self.port = ''

    def openSocketConnectionAsClient(self):
        self.port = 50000 + random.randint(1,3)
        print "Client socket port is: ", self.port
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except socket.error:
            print 'Client Failed to create socket'
            sys.exit()

        print 'Client Socket Created'

        try:
            remote_ip = socket.gethostbyname( self.host )
        except socket.gaierror:
            print 'Client Hostname could not be resolved. Exiting'
            sys.exit()

        self.socket.connect((remote_ip , self.port))

    def getData(self):
        return self.data

    def getHost(self):
        return self.host

    def getPort(self):
        return self.port

    def sendMessage(self, message):
        try :
            self.socket.sendall(message)
        except socket.error:
            print 'Client Send failed'
            os.sys.exit()

    def receiveMessageFromServer(self):
        reply = self.socket.recv(4096)
        return reply

    def closeConnection(self):
        self.socket.shutdown(1)
        self.socket.close()
        del self.socket

def clientProcess():
    print "Client Start the client process"
    client1 = ClientObject()
    for i in range(1,10): 
        try:
            print "Client try to open the connection socket: attempt number ",i
            client1.openSocketConnectionAsClient()
            print "Client connection socket established on port ", client1.getPort()
            break
        except socket.error:
            print "Client connection error on the port ", client1.getPort()
            if i == 10:
            os.sys.exit()

    print "Client send the message"
    client1.sendMessage(client1.getData())
    print "Client receive the message back"
    client1.receiveMessageFromServer()
    print "Client Data requested: ", client1.getData(), " Hostname: ", client1.getHost(), " Port: ", client1.getPort()
    print "Client Close connection"
    client1.closeConnection()

def serverProcess(port=40007):
    print "Server oject create"
    server = ServerObject(port)
    print "Server open connection as server"
    server.openSocketConnectionAsServer()
    print "Server receive the client message"
    receivedMessage = server.receiveMessageFromClient()
    message = "Server Data requested are: "+receivedMessage
    print "Server send the message back to the client"
    server.sendMessage(message)
    print "Server close the connection with the client"
    server.closeConnectionAsServer()


if __name__ == '__main__':

    threadServer = Thread(target=serverProcess, args=[50001])
    print "New Server thread created with name: ", threadServer.getName()
    threadServer.start()

    for i in range(1,3):
        threadClient = Thread(target=clientProcess)
        print "New Client thread created with name: ", threadClient.getName()
        threadClient.start()
        threadClient.join()

私がそれを実行すると、最初のクライアントはサーバーに接続できますが、最初のクライアントスレッドの最後で (サーバー側とクライアント側から) 接続を閉じても、2 番目のクライアントは接続されません。

私のコードの何が問題なのか、誰か教えてください。

ありがとう

4

2 に答える 2

0

@Ber が言ったことは正しいが不完全でした。

あなたの問題はここにあります:

self.socket.listen(5)
self.conn, addr = self.socket.accept()

listenポートを開き、接続を受信する準備をします。次の接続accept待ちます。

呼び出す必要があるのは 1 回だけですが、接続ごとに 1 回、複数回listen呼び出す必要があります。acceptこれをアレンジする方法はいくつかあります。手始めに、現在の接続が閉じられたときに再度呼び出すことができますacceptが、これにより一度に 1 つのクライアントしか許可されません。accept次の接続を待機するスレッド呼び出しを 1 つ持つ方が適切ですが、それぞれを処理するためにワーカー スレッドを開始する必要があります。

または、ノンブロッキング I/O を使用することもできますが、この方法を使用する場合はTwistedを確認してください。

于 2013-01-25T14:40:04.003 に答える
0

このようなことを行うには、優れたモジュールを使用することを強くお勧めします。socketserverコードに関しては、問題は、スレッド化されたソケット サーバーが単一のスレッドでしか実行されないことです。少なくとも、 で新しい接続を行った後、接続を処理する新しいスレッドを作成する必要がありacceptますopenSocketConnectionAsServer

于 2013-01-25T14:41:01.390 に答える