Bài giảng Lập trình mạng - Nguyễn Hoài Sơn - Lập trình UDP Socket nâng cao

Gửi tin broadcast hay multicast phải dùng UDP

Có thể dùng UDP với các ứng dụng với yêu cầu - trả lời đơn giản

Có thể dùng UDP vỚI các ứng dụng LAN

Băng thông lớn, ít lỗi

Nên dùng UDP với truyền tin đa phương tiện

Điều khiển luồng?

Dùng TCP với việc truyền dữ liệu lớn

TFTP (Trivial File Transfer Protocol) là một ngoại lệ

 

 

ppt27 trang | Chuyên mục: Lập Trình Mạng | Chia sẻ: dkS00TYs | Lượt xem: 2738 | Lượt tải: 2download
Tóm tắt nội dung Bài giảng Lập trình mạng - Nguyễn Hoài Sơn - Lập trình UDP Socket nâng cao, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
Lập trình UDP socket nâng cao TS. Nguyễn Hoài Sơn Bộ môn mạng và Truyền thông máy tính, Đại học Công nghệ, Đại học QG Hà Nội UDP hay TCP ? Gửi tin broadcast hay multicast phải dùng UDP Có thể dùng UDP với các ứng dụng với yêu cầu - trả lời đơn giản Có thể dùng UDP vỚI các ứng dụng LAN Băng thông lớn, ít lỗi Nên dùng UDP với truyền tin đa phương tiện Điều khiển luồng? Dùng TCP với việc truyền dữ liệu lớn TFTP (Trivial File Transfer Protocol) là một ngoại lệ Vấn đề với UDP Làm thế nào để lấy địa chỉ IP đích? Địa chỉ IP đích có thể là địa chỉ unicast hoặc địa chi multicast Làm thế nào biết và xử lý trong trường hợp gói tin UDP lớn hơn kích thước buffer? Làm thế nào để đảm bảo tính tin cậy khi đường truyền có lỗi Acknowledgement, timeout, gửi lại Lấy cờ hiệu, địa chỉ IP đích và số hiệu giao diện mạng Dùng sendmsg và recvmsg để lấy cờ hiệu từ socket các dữ liệu phụ thuộc như địa chỉ IP và số hiệu giao diện đích trong trường hợp có nhiều giao diện mạng Remind: sendmsg and recvmsg struct msghdr { 	void *msg_name; 	/* protocol address */ 	socklen_t msg_namelen; /* size of protocol address */ 	struct iovec *msg_iov; 	/* scatter/gather array */ 	int msg_iovlen; 	 	/* # elements in msg_iov */ 	void *msg_control; 	/* ancillary data (cmsghdr struct) */ 	socklen_t msg_controllen; 	/* length of ancillary data */ 	 	int msg_flags; 	 	 /* flags returned by recvmsg() */ 	}; #include ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags); 	Both return: number of bytes read or written if OK, –1 on error Remind: sendmsg and recvmsg (2) thiết lập cờ chức năng cho việc xuất nhập dữ liệu MSG_DONTROUTE: bỏ qua truy vấn bảng định tuyến MSG_DONTWAIT: không chờ khi xuất nhập dữ liệu MSG_OOB: gửi và nhận dữ liệu ngoài luồng (out-of-band) MSG_PEEK: kiểm tra dữ liệu vào nhưng vẫn giữ nguyên dữ liệu trong buffer MSG_WAITALL: đợi tất cả dữ liệu yêu cầu Cờ chức năng trả về bởi hàm recvmsg MSG_BCAST MSG_MCAST MSG_TRUNC Remind: Sau khi hàm recvmsg trả kết quả về Ví dụ: hàm recvfrom_flags ssize_t recvfromflags(int fd, void *ptr, size_t nbytes, int *flagsp, SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp) struct unp_in_pktinfo { struct in_addr ipi_addr; /* destination IPv4 address */ int ipi_ifindex; /* received interface index */ }; Trả về: Giá trị của msg_flags được trả về bởi hàm recvmsg Địa chỉ đích của gói tin nhận được (sử dụng tùy biến socket IP_RECVDSTADDR) Số hiệu của giao diện nhận gói tin (sử dụng tùy biến socket IP_RECVIF) Dữ liệu phụ thuộc Gửi và nhận bằng thành phần msg_control và msg_controllen của cấu trúc msghdr với hàm sendmsg và recvmsg chứa một hoặc nhiều đối tượng dữ liệu phụ thuộc each one begins with a cmsghdr structure struct cmsghdr { socklen_t cmsg_len; /* length in bytes, including this structure */ int cmsg_level; /* protocol family */ int cmsg_type; /* protocol-specific type */ /* followed by unsigned char cmsg_data[] */ }; Dữ liệu phụ thuộc chứa hai đối tượng dữ liệu Các hàm macros để đơn giản hóa xử lý dữ liệu phụ thuộc #include #include /* for ALIGN macro on many implementations */ struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *mhdrptr) ; Returns: pointer to first cmsghdr structure or NULL if no ancillary data struct cmsghdr *CMSG_NXTHDR(struct msghdr *mhdrptr, struct cmsghdr *cmsgptr) ; Returns: pointer to next cmsghdr structure or NULL if no more ancillary data objects unsigned char *CMSG_DATA(struct cmsghdr *cmsgptr) ; Returns: pointer to first byte of data associated with cmsghdr structure unsigned int CMSG_LEN(unsigned int length) ; Returns: value to store in cmsg_len given the amount of data unsigned int CMSG_SPACE(unsigned int length) ; Returns: total size of an ancillary data object given the amount of data recvfrom_flags function (2) advio/recvfromflags.c Dữ liệu phụ thuộc kiểu IP_RECVIF Hàm dg_echo với recvfrom_flags advio/dgechoaddr.c Chia nhỏ gói tin UDP Khi nhận một gói tin UDP lớn hơn kích thước buffer, hệ thống có thể xử lý theo các cách sau tùy thuộc vào từng OS Bỏ phần dữ liệu vượt quá kích thước buffer, và trả về cờ MSG_TRUNC cho tiến trình xử lý recvmsg thiết lập cờ MSG_TRUNC trong msg_flags của cấu trúc msghdr Bỏ phần dữ liệu thừa và không thông báo cho tiến trình xử lý Giữ phần dữ liệu thừa và trả về ở lần đọc dữ liệu socket sau đó => cần thiết lập kích thước buffer lớn hơn kích thước lớn nhất của gói tin UDP có thể nhận được một byte Tạo tính tin cậy cho ứng dụng UDPs Thực hiện 2 yêu cầu Số thứ tự (Sequence numbers): Bên nhận xác nhận số thứ tự của thông báo nhận được Client thêm số thứ tự vào mỗi thông báo yêu cầu và máy chủ gửi lại số thứ tự này trong thông báo trả lời Timeout và gửi lại: khôi phục các gói tin bị mất mát Gửi thông báo yêu cầu và đợi trong N giây Nếu không có thông báo trả lời, gửi lại và đợi thêm N giây Lặp lại nhiều lần Tạo tính tin cậy cho ứng dụng UDPs (2) Làm thế nào để xác định N thích hợp? RTT trong mạng LAN và WAN là khác nhau RTT giữa máy khách và máy chủ có thể thay đổi nhanh chóng Cần tính toán RTT thực sự => Giải pháp từ [Jacobson 1988] g = 1/8, h = 1/4 Vấn đề không rõ ràng khi gửi lại Thông báo yêu cầu bị mất? Thông báo trả lời bị mất? Khoảng RTO là quá nhỏ? RTT là bao nhiêu? Giải pháp Thêm nhãn thời gian vào mỗi thông báo và máy chủ cũng phải gửi lại nhãn thời gian này Tính toán RTT bằng thời gian nhận gói tin trừ đi nhãn thời gian ghi trong gói tin => Hàm dg_send_recv struct rtt_info struct rtt_info { float rtt_rtt; /* RTT gần nhất, đơn vị giây */ float rtt_srtt; /* Ước lượng RTT, đơn vị giây */ float rtt_rttvar; /* Ước lượng độ lệch trung bình, đơn vị giây */ float rtt_rto; /* RTT hiện tại, đơn vị giây */ int rtt_nrexmt; /* số lần gửi lại: 0, 1, 2, ... */ uint32_t rtt_base; /* thời gian (giây) tính từ 1/1/1970 */ }; dg_send_recv function rtt/dg_send_recv.c g = 1/8, h = 1/4 Các bước thực hiện Khởi tạo đồng hồ đếm độ trễ Khởi tạo dữ liệu gửi msgsend Tiêu đề chứa sequence number và nhãn thời gian Đặt tín hiệu chuông Thời gian đổ chuông ban đầu = độ trễ ước lượng Chờ và nhận gói tin trả lời Tính toán lại độ trễ ước lượng alarm(rtt_start(&rttinfo)) rtt_init(&rttinfo) rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts) timeout Các hàm tính toán độ trễ lib/rtt.c rtt_init rtt_ts, rtt_newpack, rtt_start, rtt_stop Xuất nhập dữ liệu I/O bằng điều khiển tín hiệu Mô hình xuất nhập dữ liệu bằng điều khiển tín hiệu recvfrom application kernel sigaction system call datagram ready copy datagram copy complete wait for data copy data from kernel to user process datagram process continues executing return OK establish SIGIO signal handler deliver SIGIO system call process blocks while data is copied into application buffer return signal handler Các bước thực hiện xuất nhập dữ liệu bằng điều khiển tín hiệu Thiết lập hàm xử lý tín hiệu SIGIO Thiết lập chủ sở hữu socket sử dụng lệnh F_SETOWN của hàm fcntl Cho phép xuất nhập dữ liệu bằng điều khiển tín hiệu sử dụng lệnh F_SETFL của hàm fcntl để thiết lập cờ O_ASYNC SIGIO với UDP Sockets Tín hiệu SIGIO được sinh ra khi Socket nhận được một gói tin Lỗi không đồng bộ xuất hiện tại socket SIGIO với TCP Sockets Nhiều điều kiện để tạo ra tín hiệu SIGIO Một yêu cầu kết nối kết thúc tại socket lắng nghe Một yêu cầu kết nối được khởi tạo Một yêu cầu ngắt kết nối được hoàn thành Một nửa kết nối bị đóng Dữ liệu đến socket Dữ liệu được gửi từ socket Lỗi không đồng bộ xuất hiện => Ít sử dụng SIGIO với TCP socket Máy chủ UDP Echo sử dụng SIGIO sigio/dgecho01.c Đặt dữ liệu nhận được trong hàng đợi dữ liệu chờ xử lý Sau khi xử lý tín hiệu SIGIO, tăng biến đếm của hàng đợi nqueue Gửi lại dữ liệu nhận được khi biến đếm của hàng đợi khác 0 Điều gì xảy ra nếu tín hiệu SIGIO không bị chặn trong khi chương trình kiếm tra biến nqueue ? 

File đính kèm:

  • pptBài giảng Lập trình mạng - Nguyễn Hoài Sơn - Lập trình UDP Socket nâng cao.ppt