Socket Programming Issue - Python
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 SocketSer开发者_运维技巧ver
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
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()
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()
精彩评论