Reputation: 567
I'm trying to implement a small chat server-client pair in Python. I have already written both my server and my client, but I'm having a little problem trying to run the server on my website.
This example is from the docs. I modified it a little bit to support multiple clients:
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 9090
BUFFER_SIZE = 256
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
while True:
conn, addr = s.accept()
print('Connection address:', addr)
while True:
data = conn.recv(BUFFER_SIZE)
if not data: continue
# handle the request
conn.close()
This server uses a while loop, which means that it should only be run once. However, I can't figure out how to run the server only once.
I understand that I had to do socket.accept()
inside a while
loop in order to work with more than one client, but the problem is actually running it on my web server and making it wait for connections forever.
Help me! ~Chance
Upvotes: 0
Views: 7303
Reputation: 312
Note: this refers to the initial code sample, not to subsequent comments.
So, not sure which doc you pulled this code sample from. If you could include a link to that, that would be great.
I think you may need change to this line:
if not data: continue
To this:
if not data: break
From what I recall "continue" will discard executing the remaining statements and immediately take you back up to the top of the loop, while "break" will take you to the bottom of the loop, which should permit the rest of the logic to close connection to do its job.
From what I can glean, this will allow one connection, then not seem to do anything afterwards with subsequent connection attempts. I think this is what you mean by "running forever." As in, running, but not seeming to respond to subsequent requests, no?
Upvotes: 1
Reputation: 567
To fix the multiple clients problem:
#!/usr/bin/env python
import threading
import socket
clients = {}
class ClientThread(threading.Thread):
def __init__(self, conn, addr):
threading.Thread.__init__(self)
self.conn = conn
self.addr = addr
print("Connected to", str(self))
def __str__(self):
return "{0}:{1}".format(*self.addr)
def run(self):
while True:
try:
data = self.conn.recv(256)
except socket.error:
print("Disconnected from", str(self))
break
if not data: continue
k = str(data, "UTF-8")
print(k)
if k.startswith("LOGN"):
name = k.split()[1]
clients[name] = self
self.conn.send(bytes("[SVR] Logged in as @" + name + "\n", "UTF-8"))
elif k == "QUIT": break
conn.close()
TCP_IP = '127.0.0.1'
TCP_PORT = 9090
BUFFER_SIZE = 256
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
while True:
conn, addr = s.accept()
ClientThread(conn, addr).start()
But I still can't figure out how to run it on my website.
Upvotes: 0
Reputation: 11322
For one thing, your server will handle multiple clients, but only one at a time. This is not so bad for request-response based servers (like a HTTP server). In your case, you probably want to keep an open connection to each client.
You might want to take a look at the SocketServer library. This library will help you create a server that will handle multiple clients at the same time. For this you can use an ThreadingMixin.
The example provided for this library is very much like a Chat Server, so you could use it as a basis for your own code.
In the server you need to create list of connected clients. You should create a RequestHandlder that will read incoming data from the clients in an infinite loop. Upon receiving data from the client, it should send the data to all other clients in the list.
Upvotes: 1
Reputation: 4053
Simple problem. 1) Your nested while loop have no end. So you will receive data from just one client. 2) You probably need separate threads for each new connection. Something like:
While True:
if new_connection:
launch_new_thread_for_it
3) Remember to discover situation when client disconnect! No point in checking if there is new data if client is gone.
Upvotes: 0