Tôi đang làm việc trên một chương trình truyền tệp đáng tin cậy sử dụng UDP. (. Cho một khóa học về mạng máy tính)Cuộc gọi liên tiếp để recvfrom() mất dữ liệu?
Câu hỏi của tôi là thế này - tốt, xem xét tình huống này:
Sender có (ví dụ) 12 byte dữ liệu để gửi. Vì vậy, người gửi thực hiện cuộc gọi này:
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
Điều này sẽ gửi 12 byte dữ liệu một cách không đáng tin cậy. 4 byte đầu tiên của dữ liệu này xảy ra là trường "độ dài tin nhắn". Trong trường hợp này, 4 byte đầu tiên có thể có giá trị 0x0000000C
Người nhận muốn đọc 4 byte đầu tiên bằng cách sử dụng recvfrom(). Thấy rằng kích thước phân đoạn là 12 byte, nó muốn đọc 8 byte còn lại. Vì vậy, người nhận có thể trông như thế này:
/* read the segment size */ recvfrom(sockfd,&buf,4,0,(struct sockaddr *)&cliaddr,&len); /* do some arithmetic, use bzero(), etc */ /* read the rest of the data */ recvfrom(sockfd,&buf,8,0,(struct sockaddr *)&cliaddr,&len);
Khi tôi thực thi mã này, tôi có thể nhận được 4 byte đầu tiên mà không có một vấn đề. Nhưng khi tôi cố gắng lấy dữ liệu còn lại, dữ liệu đó dường như bị mất. Trong đầu ra của tôi, tôi nhận được rác - có vẻ như một số phần của tiếp theo 12 byte mà người gửi là sendto() - ing.
Hành vi này có được mong đợi không? Đó là để nói, nếu một cuộc gọi recvfrom() không đọc tất cả dữ liệu được gửi đi, có phải là nó không đảm bảo rằng dữ liệu đó (8 byte còn lại) có sẵn cho tôi không?
Dường như phương pháp gửi tiêu đề phân đoạn chuẩn (bao gồm kích thước của nó), tiếp theo là tải trọng, không hoạt động. Điều đó có nghĩa là tôi cần phải gửi 2 phân đoạn riêng biệt - một phân đoạn chỉ chứa thông tin tiêu đề và sau đó là phân khúc thứ 2 có trọng tải? Hay tôi chỉ sử dụng các syscalls sai (hoặc là có một lá cờ hoặc setsockopt() mà tôi đang thiếu?)
Vấn đề là UDP là giao thức kiểu gói, không phải là giao thức kiểu đường ống. Vì vậy, nó cần phải cung cấp cho bạn toàn bộ gói trong một lần chụp, để bạn có thể biết nơi gói tin bắt đầu một kết thúc.Nếu không, bạn không có đầu mối những gì đã thực sự xảy ra. –