简体   繁体   English

Python客户端套接字在同一服务器套接字端口上连接

[英]Python client sockets connecting on the same server socket port

I am working for the first time on sockets with python. 我是第一次使用python在套接字上工作。 I need to connect more than a client socket to the same server socket. 我需要将多个客户端套接字连接到同一服务器套接字。

To do this I used the the following code: 为此,我使用了以下代码:

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

When I run it, the first client is able to connect to the server, the second one never get connected, even though I close the connection (from server and client side) at the end of the first client thread. 当我运行它时,即使我在第一个客户端线程的末尾关闭了连接(从服务器和客户端),第一个客户端也可以连接到服务器,而第二个客户端却无法连接。

Please, could anybody tell me, what's wrong in my code? 拜托,有人可以告诉我,我的代码有什么问题吗?

Thanks 谢谢

What @Ber said was correct but incomplete. @贝尔所说的是正确的,但不完整。

You're problem is here: 您的问题在这里:

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

listen will open up the port and prepare to receive connections. listen将打开端口并准备接收连接。 accept will wait for the next connection. accept等待下一个连接。

While you only need to call listen once, you must call accept multiple times, once per connection. 虽然您只需要调用一次listen ,但是您必须多次调用accept ,每个连接一次。 There are several ways you can arrange this. 您可以通过多种方式进行安排。 For starters you could call accept again when the current connection closes, but this will only allow one client at a time. 对于初学者,您可以在当前连接关闭时再次调用accept ,但这一次仅允许一个客户端。 Better to have one thread call accept to wait for the next connection, but have it start a worker thread to handle each one. 最好让一个线程调用accept以等待下一个连接,但是让它启动一个工作线程来处理每个连接。

Or you could use non-blocking I/O , but if you go this way, check out Twisted . 或者,您可以使用非阻塞I / O ,但如果采用这种方式,请查看Twisted

I would highly recommend using the excellent socketserver module for doing stuff like this. 强烈建议使用出色的socketserver模块来完成类似的工作。 As for your code, the problem is that your threaded socket server only runs in a single thread. 至于您的代码,问题在于您的线程套接字服务器仅在单个线程中运行。 At the very least, you should create a new thread to handle the connection after accept ing the new connection in openSocketConnectionAsServer . 至少,在openSocketConnectionAsServer accept新连接后,您应该创建一个新线程来处理该连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM