3

Alright, I've spent about three hours fiddling with socket programming in Python trying to make a simple chat program. I've gotten the client to send text to the server and then, from then client, it repeats the message to it's self. However, I want the message to be sent to the server and then the server, not the client, re-send it to all client's connected. I'm having issues doing this. This is my code so far:

Server Side Code:

import SocketServer
 def handle(self):
 data = self.request[0].strip()
 socket = self.request[1]
 print "%s wrote:" % self.client_address[0]
 print data
 socket.sendto(data.upper(), self.client_address)
if __name__ == "__main__":
 HOST, PORT = "localhost", 25555
 server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
 server.serve_forever()

Client Side Code:

import socket
import sys
global HOST
global PORT
HOST, PORT = "localhost", 25555
while 1 > 0:
 data = raw_input(">".join(sys.argv[1:]))
# SOCK_DGRAM is the socket type to use for UDP sockets
 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# As you can see, there is no connect() call; UDP has no connections.
# Instead, data is directly sent to the recipient via sendto().
 sock.sendto(data + "\n", (HOST, PORT))
 received = sock.recv(1024)
 print "Sent: %s" % data
 print "Received: %s" % received
asked Feb 5, 2011 at 1:41

2 Answers 2

1

Right now your app is instantiating the MyUDPHandler class for each client connection. When the connection is opened you need to store that instance to a static array or queue. Then when the handle() call is made it can loop through all those sockets and send a copy of the data to each of them.

I'd checkout the python documentation; it basically does what your looking to: http://docs.python.org/library/socketserver.html#asynchronous-mixins

And what I'd change from that example (Don't just drop this in; it probably has glaring bugs!):

handlerList = []
class ...
 def handle(self):
 handlerList.append(self)
 while (1):
 data = self.request.recv(1024)
 if (not data):
 break
 cur_thread = threading.currentThread()
 response = "%s: %s" % (cur_thread.getName(), data)
 for x in handlerList:
 x.request.send(response)
 psudo_code_remove_self_from_handlerList()
answered Feb 5, 2011 at 1:53
Sign up to request clarification or add additional context in comments.

4 Comments

Is there a tutorial on doing this? If not, could you please provide an example?
Is your intention to open a new UDP connection for each line? Right now it looks like you renegotiate a new socket each time.
Using threads you can keep the same socket open to rx/tx the data back and forth. Without the thread mixin you have to handle a new UDP request each time as the handle() call is synchronous (can't handle a new one until the last one is done). This makes it difficult as I was trying to store the handler object so you can go through the list and send the data on each one.
The code you gave me has a lot of errors.... could you revise it before I accept an answer... and thanks for the explanations...
1

Would you like to play with a server that echos packets to all sockets but the original source of the data?

import socket, select
def main():
 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 server.bind(('', 8989))
 server.listen(5)
 sockets = [server]
 while True:
 for sender in select.select(sockets, [], [])[0]:
 if sender is server:
 sockets.append(server.accept()[0])
 else:
 try:
 message = sender.recv(4096)
 except socket.error:
 message = None
 if message:
 for receiver in sockets:
 if receiver not in (server, sender):
 receiver.sendall(message)
 else:
 sender.shutdown(socket.SHUT_RDWR)
 sender.close()
 sockets.remove(sender)
if __name__ == '__main__':
 main()
answered Feb 5, 2011 at 5:56

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.