Lập trình mạng Python: giao thức UDP (phần 2)

Sockets (tiếp tục)

Sockets trông là gì trong hoạt động? Nhìn vào phần code dưới, cái thể hiện một UDP
server và client đơn giản. Bạn có thể đã thấy rằng nó chỉ thực hiện một Python Standard
Library call tới hàm socket.socket(), và rằng tất cả các lời gọi khác là tới các
phương thức của socket object nó trả về.

UDP Server and Client on the Loopback Interface
#!/usr/bin/env python3
# Foundations of Python Network Programming, Third Edition
# https://github.com/brandon-rhodes/fopnp/blob/m/py3/chapter02/udp_local.py
# UDP client and server on localhost
import argparse, socket
from datetime import datetime
MAX_BYTES = 65535
def server(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((‘127.0.0.1’, port))
print(‘Listening at {}’.format(sock.getsockname()))
while True:
data, address = sock.recvfrom(MAX_BYTES)
text = data.decode(‘ascii’)
print(‘The client at {} says {!r}’.format(address, text))
text = ‘Your data was {} bytes long’.format(len(data))
data = text.encode(‘ascii’)
sock.sendto(data, address)
def client(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = ‘The time is {}’.format(datetime.now())
data = text.encode(‘ascii’)
sock.sendto(data, (‘127.0.0.1’, port))
print(‘The OS assigned me the address {}’.format(sock.getsockname()))
data, address = sock.recvfrom(MAX_BYTES) # Danger!
text = data.decode(‘ascii’)
print(‘The server {} replied {!r}’.format(address, text))
if __name__ == ‘__main__’:
choices = {‘client’: client, ‘server’: server}
parser = argparse.ArgumentParser(description=’Send and receive UDP locally’)
parser.add_argument(‘role’, choices=choices, help=’which role to play’)
parser.add_argument(‘-p’, metavar=’PORT’, type=int, default=1060,
help=’UDP port (default 1060)’)
args = parser.parse_args()
function = choices[args.role]
function(args.p)

Bạn có thể chạy script này ngay trên máy tính của bạn, thậm chí nếu bạn hiện tại không trong phạm vi một
mạng, vì cả server và client chỉ sử dụng địa chỉ IP localhost, cái sẽ có sẵn bất kể bạn có kết nối với một
mạng thực hay không. Thử khởi động server trước.

$ python udp_local.py server
Listening at (‘127.0.0.1’, 1060)

Sau khi in ra dòng này của đầu ra, server chờ cho một thông điệp đi đến.
Trong mã nguồn, bạn có thể thấy rằng nó thực hiện 3 bước cho server hoạt động và chạy.
Nó trước tiên tạo một plain socket với lời gọi socket(). Socket mới này chưa gắn với 1 địa chỉ IP hay số cổng,
chưa kết nối với bất cứ thứ gì, và sẽ dấy một ngoại lệ nếu bạn thử sử dụng nó để trao đổi thông tin.
Tuy nhiên, socket được, ít nhất, đánh dấu như thuộc một dạng cụ thể: family của nó là AF_INET, Internet family
của các giao thức, và nó thuộc dạng SOCK_DGRAM datagram, cái có nghĩa nó sẽ sử dụng UDP trên một mạng IP. Chú
ý rằng thuật ngữ datagram (không phải là packet) là thuật ngữ chính thức cho một khối dữ liệu được truyền mức ứng
dụng vì stack liên mạng hệ điều hành không đảm bảo rằng một packet đơn trên mạng sẽ thực sự trình bày một datagram
đơn (Xem học phần sau nơi tôi bám vào một tương ứng 1-1 giữa các datagrams và packets để rằng bạn có thể đo lường
maximum transmission unit [MTU].)

Chia sẻ

Leave a Reply

Your email address will not be published. Required fields are marked *