Python 套接字编程问题
好的,我花了大约三个小时在Python中研究socket编程,想做一个简单的聊天程序。我已经让客户端可以把文字发送到服务器,然后客户端又把这个消息重复给自己。不过,我希望消息能先发送到服务器,然后由服务器把它重新发送给所有连接的客户端,而不是让客户端自己重复。我在实现这个功能时遇到了一些问题。以下是我目前的代码:
服务器端代码:
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()
客户端代码:
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
2 个回答
1
你想试试一个服务器吗?这个服务器会把收到的数据包发给所有的连接,但不会发给最初发送这些数据的那个地方。
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()
1
现在你的应用程序为每个客户端连接都创建了一个MyUDPHandler类的实例。当连接打开时,你需要把这个实例存储到一个静态数组或队列里。然后,当调用handle()时,它可以遍历所有这些套接字,并把数据的副本发送给每一个。
我建议你看看Python的文档;它基本上就是你想要的功能: http://docs.python.org/library/socketserver.html#asynchronous-mixins
还有,我会对那个例子做一些修改(不要直接把它放进去;它可能有明显的错误!):
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()