我第一次使用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()
当我运行它时,第一个客户端能够连接到服务器,第二个客户端永远不会连接,即使我在第一个客户端线程结束时关闭连接(从服务器和客户端)。
拜托,有人能告诉我,我的代码有什么问题吗?
由于
答案 0 :(得分:0)
@Ber所说的是正确但不完整的。
你的问题在这里:
self.socket.listen(5)
self.conn, addr = self.socket.accept()
listen
将打开端口并准备接收连接。 accept
将等待以进行下一次连接。
虽然您只需拨打listen
一次,但您必须多次拨打accept
,每次连接一次。有几种方法可以安排这个。对于初学者,您可以在当前连接关闭时再次呼叫accept
,但这一次只允许一个客户端。最好让一个线程调用accept
来等待下一个连接,但是让它启动一个工作线程来处理每个连接。
或者您可以使用non-blocking I/O,但如果您这样做,请查看Twisted。
答案 1 :(得分:0)
我高度建议使用优秀的socketserver
模块来执行此类操作。至于您的代码,问题是您的线程套接字服务器只在单个线程中运行。至少,您应该在accept
中openSocketConnectionAsServer
新连接后创建一个新线程来处理连接。