在同一服务器套接字端口上连接的Python客户端套接字 [英] Python client sockets connecting on the same server socket port

查看:106
本文介绍了在同一服务器套接字端口上连接的Python客户端套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次使用python在套接字上工作. 我需要将多个客户端套接字连接到同一服务器套接字.

I am working for the first time on sockets with 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?

谢谢

推荐答案

@Ber所说的正确但不完整.

What @Ber said was correct but incomplete.

您的问题在这里:

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

listen将打开端口并准备接收连接. accept等待进行下一个连接.

listen will open up the port and prepare to receive connections. accept will wait for the next connection.

虽然只需要调用一次listen,但是必须多次调用accept,每个连接一次.您可以通过几种方法进行安排.对于初学者,您可以在当前连接关闭时再次调用accept,但这一次仅允许一个客户端.最好让一个线程调用accept等待下一个连接,但是让它启动一个工作线程来处理每个连接.

While you only need to call listen once, you must call accept multiple times, once per connection. 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. Better to have one thread call accept to wait for the next connection, but have it start a worker thread to handle each one.

或者您可以使用非阻塞I/O ,但是如果您采用这种方式,请查看扭曲.

Or you could use non-blocking I/O, but if you go this way, check out Twisted.

这篇关于在同一服务器套接字端口上连接的Python客户端套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆