代码清单2-2 运行在不同机器上的UDP服务器与客户端

代码清单2-2 运行在不同机器上的UDP服务器与客户端

import argparse
import random
import socket

MAX_BYTES = 65535


def server(interface, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 建立socket连接,使用IPv4及UDP协议
    sock.bind((interface, port))  # 与(IPv4,port)地址对进行绑定
    print('Listening at', sock.getsockname())  # 返回自己绑定的地址对
    while True:
        data, address = sock.recvfrom(MAX_BYTES)  # 返回接收到的数据,以及发送端的IPv4地址
        if random.random() < 0.5:  # 随机生成0-1的随机数,有0.5的概率执行以下命令
            print('Pretending to drop packet from {}'.format(address))  # 打印发送数据端的地址
            continue  # 直接退出当前循环,发送端将不会收到回复
        text = data.decode('ascii')  # 将数据进行解码
        print('The client at {} says {!r}'.format(address, text))
        message = 'Your data was {} bytes long'.format(len(data))
        sock.sendto(message.encode('ascii'), address)  # 将回复发送给客户端


def client(hostname, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.connect((hostname, port))  # 与服务器建立连接,有地一定概率会连接超时从而返回超时错误
    print('Client socket name is {}'.format(sock.getsockname()))  # 打印自己的IPv4地址及端口号
    delay = 0.1  # 延迟0.1s
    text = 'This is another message'
    data = text.encode('ascii')  # 将要发送的信息进行编码
    while True:
        sock.send(data)  # 发送数据 能够进行到这一步说明可以连接到服务端
        print('Waiting up to {} seconds for a reply'.format(delay))
        sock.settimeout(delay)
        try:
            data = sock.recv(MAX_BYTES)
        except socket.timeout:
            delay = delay*2  # 再等一段时间发起下一次请求
            if delay > 2.0:
                raise RuntimeError('I think the server is down')  # 如果超过两次依旧没有回复,认为服务器坏掉了
        else:
            break  # 直接不再循环,停止运行
    print('The server says {!r}'.format(data.decode('ascii')))


choices = {
    
    'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive UDP,' 'pretending packets are often dropped')
parser.add_argument('role', choices=choices, help='which role to take')  # 第一个参数决定是客户端还是服务端
parser.add_argument('host',
                    help='interface the server listens at:' 'host the client sends to')  # 第二个参数既是服务器的IPv4地址,也是客户端要发送的地址
parser.add_argument('-p', metavar='PORT', type=int, default=1060, help='UDP port(default = 1060)')  # 第三个参数1是服务器UDP的端口号
args = parser.parse_args()  # 将输入的参数赋给args
function = choices[args.role]
function(args.host, args.p)

猜你喜欢

转载自blog.csdn.net/hjz2196987870/article/details/127974827