问题
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?
Thanks
回答1:
I would highly recommend using the excellent socketserver module for doing stuff like this. 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
.
回答2:
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. accept
will wait for the next connection.
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.
Or you could use non-blocking I/O, but if you go this way, check out Twisted.
来源:https://stackoverflow.com/questions/14523767/python-client-sockets-connecting-on-the-same-server-socket-port