Reputation: 1838
What I'm trying to program is a simple multithreaded python game server for fun. After much frustration, I've not been able to figure out why my test client connection times out. Here's my server.py code:
import socket
import threading
import clientThread
import struct
import string
class Server:
def __init__(self):
self.HOST = 'localhost'
self.PORT = 22085
self.BUFFIZE = 1024
self.ADDRESS = (self.HOST,self.PORT)
self.clientList = []
input("Press enter to start the server. . .")
self.running = True
self.serverSock = socket.socket()
self.serverSock.bind(self.ADDRESS)
self.serverSock.listen(2)
self.clientThread = clientThread.clientThread(self)
print("Starting client thread. . .")
self.clientThreadObj = threading.Thread(target = self.clientThread.start, args = (self))
print("Awaiting connections. . .")
while self.running:
clientInfo = self.serverSock.accept()
print("Client connected from %s." % clientInfo[1])
# Append to clientThread list...
self.serverSock.close()
print("- end -")
serv = Server()
The server starts the thread for existing connections and starts listening. The thread built for existing connections, clientThread
, loops through a list of client objects which for now do nothing, they are simply architectural. Here is the clientThread.py
import socket
import threading
import struct
import string
class clientThread:
def __init__(self, serv):
self.server = serv
self.clientList = []
self.running = True
print("Client thread created. . .")
def start(self):
print("Beginning client thread loop. . .")
while self.running:
for client in self.clientList:
message = client.sock.recv(self.server.BUFFSIZE)
if message != None and message != "":
client.update(message)
And finally, the very simple client object:
import string
class clientObject:
def start(self,clientInfo):
self.sock = clientInfo[0]
self.address = clientInfo[1]
def update(self,message):
self.sock.send("Testamundo.\r\n".encode())
Now, the problem here is that my client can't even connect to my server. It simply times out. Here is the code for my simple client test:
import socket
import string
address = ("192.168.1.1",22085)
mySocket = socket.socket()
mySocket.connect(address)
print("Connected successfully!")
This returns on the line that connects to address, "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond."
Any suggestions? Thanks! Sorry for all this code, I wasn't sure if I needed to post it all or not, so I figured it couldn't hurt too much.
Upvotes: 3
Views: 13547
Reputation: 177406
Do you have two systems? Does the server system have an IP of 192.168.1.1? If you only have one system, the localhost address is 127.0.0.1. That was the first change I had to make to your code to get a connection when running the server and client on the same system.
Another issue is your client thread doesn't actually start. Since you want a client thread class, here's how to declare and start it:
__init__
for your behavior, but call __init__
in the base class first.run
for the thread work.start
method.Another problem is recv
blocks if the client hasn't sent any data, so if you try to connect multiple clients it will hang in your loop over the client list. You'll need a thread per client or use select.select
to query the client sockets for read/write readiness.
Below is the changed code that got a single client to respond, but it needs work to handle multiple clients. It also needs to set up a protocol to handle messages. TCP is a streaming protocol (no message boundaries), so a send of 'abc' and '123' could result in a receive of 'abc123' or 'ab' and 'c123', etc. It'll have to handle closing the connections and remove the client objects from the client list as well.
Good luck! You'll learn a lot figuring out how to do all this from scratch. Look at the socketserver.py
library as well for example code.
import socket
import threading
import struct
import string
class clientThread(threading.Thread):
def __init__(self, serv):
threading.Thread.__init__(self)
self.server = serv
self.clientList = []
self.running = True
print("Client thread created. . .")
def run(self):
print("Beginning client thread loop. . .")
while self.running:
for client in self.clientList:
message = client.sock.recv(self.server.BUFFSIZE)
if message != None and message != "":
client.update(message)
class clientObject(object):
def __init__(self,clientInfo):
self.sock = clientInfo[0]
self.address = clientInfo[1]
def update(self,message):
self.sock.send("Testamundo.\r\n".encode())
class Server(object):
def __init__(self):
self.HOST = 'localhost'
self.PORT = 22085
self.BUFFSIZE = 1024
self.ADDRESS = (self.HOST,self.PORT)
self.clientList = []
input("Press enter to start the server. . .")
self.running = True
self.serverSock = socket.socket()
self.serverSock.bind(self.ADDRESS)
self.serverSock.listen(2)
self.clientThread = clientThread(self)
print("Starting client thread. . .")
self.clientThread.start()
print("Awaiting connections. . .")
while self.running:
clientInfo = self.serverSock.accept()
print("Client connected from {}.".format(clientInfo[1]))
self.clientThread.clientList.append(clientObject(clientInfo))
self.serverSock.close()
print("- end -")
serv = Server()
import socket
import string
address = ('localhost',22085)
mySocket = socket.socket()
mySocket.connect(address)
print("Connected successfully!")
mySocket.send('blah'.encode())
print(mySocket.recv(1024))
Press enter to start the server. . .
Client thread created. . .
Starting client thread. . .
Beginning client thread loop. . .
Awaiting connections. . .
Client connected from ('127.0.0.1', 52850).
Connected successfully!
b'Testamundo.\r\n'
Upvotes: 7