通过 UDP 重复通信
Repeating Communications Over UDP
当根据需要创建 TCPServer
from the socketserver
module, a connection can be made and used continually for communication until one side execute a shutdown
command. Having written the following programs, it is unclear to me how to continue communicating with the server if (for various reasons) a UDPServer
is required for use. Should the client keep running the sendto
and recv
方法并假装服务器将收到消息并 return 回复时?
客户端
import socket
import sys
def main():
host, port = 'localhost', 10000
data = ' '.join(sys.argv[1:])
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(data.encode(), (host, port))
received = client.recv(1 << 12).decode()
print('Sent: ', data)
print('Received:', received)
if __name__ == '__main__':
main()
服务器
import socketserver
def main():
host, port = 'localhost', 10000
server = socketserver.UDPServer((host, port), UDPHandler)
server.serve_forever()
class UDPHandler(socketserver.DatagramRequestHandler):
def handle(self):
data = self.rfile.read().strip()
client, port = self.client_address
print(client, 'wrote:', data)
self.wfile.write(data.upper())
if __name__ == '__main__':
main()
由于使用数据报时不存在有保证的连接,客户端可能会继续向服务器发送消息并尝试接收回复。在连接、关闭或关闭套接字方面没有什么特别要做的。服务器应该像以前一样使用适当编写的处理程序来接收和发送客户端通信。以下示例演示了如何编写此类程序并包括用于指定其参数的命令行界面。
UDPClient.py
#! /usr/bin/env python3
import argparse
import socket
def main():
parser = argparse.ArgumentParser(description='Execute a UDP client demo.')
parser.add_argument('host', type=str, help='computer where data is sent')
parser.add_argument('port', type=int, help='location where server listens')
arguments = parser.parse_args()
address = arguments.host, arguments.port
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for _ in range(5):
message = input('>>> ').encode('ascii')
client.sendto(message, address)
response = client.recv(1 << 12).decode('ascii')
print(response)
if __name__ == '__main__':
main()
UDPServer.py
#! /usr/bin/env python3
import argparse
import socketserver
def main():
parser = argparse.ArgumentParser(description='Execute a UDP server demo.')
parser.add_argument('port', type=int, help='where the server will listen')
arguments = parser.parse_args()
host = socketserver.socket.gethostbyname(socketserver.socket.gethostname())
address = host, arguments.port
server = socketserver.ThreadingUDPServer(address, ClientRequestHandler)
server.serve_forever()
class ClientRequestHandler(socketserver.DatagramRequestHandler):
def handle(self):
message = self.rfile.read().decode('ascii')
print('Received:', message)
response = 'Received: {}'.format(message).encode('ascii')
self.wfile.write(response)
if __name__ == '__main__':
main()
当根据需要创建 TCPServer
from the socketserver
module, a connection can be made and used continually for communication until one side execute a shutdown
command. Having written the following programs, it is unclear to me how to continue communicating with the server if (for various reasons) a UDPServer
is required for use. Should the client keep running the sendto
and recv
方法并假装服务器将收到消息并 return 回复时?
客户端
import socket
import sys
def main():
host, port = 'localhost', 10000
data = ' '.join(sys.argv[1:])
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto(data.encode(), (host, port))
received = client.recv(1 << 12).decode()
print('Sent: ', data)
print('Received:', received)
if __name__ == '__main__':
main()
服务器
import socketserver
def main():
host, port = 'localhost', 10000
server = socketserver.UDPServer((host, port), UDPHandler)
server.serve_forever()
class UDPHandler(socketserver.DatagramRequestHandler):
def handle(self):
data = self.rfile.read().strip()
client, port = self.client_address
print(client, 'wrote:', data)
self.wfile.write(data.upper())
if __name__ == '__main__':
main()
由于使用数据报时不存在有保证的连接,客户端可能会继续向服务器发送消息并尝试接收回复。在连接、关闭或关闭套接字方面没有什么特别要做的。服务器应该像以前一样使用适当编写的处理程序来接收和发送客户端通信。以下示例演示了如何编写此类程序并包括用于指定其参数的命令行界面。
UDPClient.py
#! /usr/bin/env python3
import argparse
import socket
def main():
parser = argparse.ArgumentParser(description='Execute a UDP client demo.')
parser.add_argument('host', type=str, help='computer where data is sent')
parser.add_argument('port', type=int, help='location where server listens')
arguments = parser.parse_args()
address = arguments.host, arguments.port
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for _ in range(5):
message = input('>>> ').encode('ascii')
client.sendto(message, address)
response = client.recv(1 << 12).decode('ascii')
print(response)
if __name__ == '__main__':
main()
UDPServer.py
#! /usr/bin/env python3
import argparse
import socketserver
def main():
parser = argparse.ArgumentParser(description='Execute a UDP server demo.')
parser.add_argument('port', type=int, help='where the server will listen')
arguments = parser.parse_args()
host = socketserver.socket.gethostbyname(socketserver.socket.gethostname())
address = host, arguments.port
server = socketserver.ThreadingUDPServer(address, ClientRequestHandler)
server.serve_forever()
class ClientRequestHandler(socketserver.DatagramRequestHandler):
def handle(self):
message = self.rfile.read().decode('ascii')
print('Received:', message)
response = 'Received: {}'.format(message).encode('ascii')
self.wfile.write(response)
if __name__ == '__main__':
main()