Tôi đã đọc tài liệu ít nhất 10 lần và cũng đã đọc khoảng 10 đoạn mã hoặc chương trình đầy đủ nơi các ổ cắm không chặn được sử dụng để gửi dữ liệu. Vấn đề là một số hướng dẫn hoặc là cho người mới bắt đầu (Beejs f.i.) hoặc khá cẩu thả trong các giả định của họ; và những người không phức tạp là những ví dụ mã chuyên biệt không giải thích lý do tại sao họ làm những gì họ làm. Ngay cả cơ sở tri thức SO cũng không bao quát toàn bộ gam màu của hành vi send
, theo ý kiến của tôi. Những gì tôi sau đây là chi tiết về f.e:Ai đó có thể cho tôi giải thích tốt về hành vi 'gửi' cho các ổ cắm không chặn không?
- Mã trả về 0 cho biết chính xác và có giá trị khi kiểm tra
errno
sau đó hoặc nên bỏ kết nối mà không cần điều tra thêm? - Việc nhận được lệnh bảo đảm giá trị trả lại âm có kết thúc không tốt hoặc chỉ trừ khi
errno
làEWOULDBLOCK
,EAGAIN
hoặcEINTR
(... người khác)? - Có đáng để kiểm tra
errno
khi giá trị trả lại là> 0
? Rõ ràng, giá trị cho biết số lượng dữ liệu "đã gửi" (trong dấu ngoặc kép vì nó là một quá trình dài thực sự, phải), nhưng vì ổ cắm không bị chặn, có nghĩa là người dùng có thể thực hiện cuộc gọi khác ngay lập tức hoặc tùy thuộc vàoerrno
một lần nữa , người ta có nên đợi cho dịp gửi tiếp theo (sử dụng select/poll/epoll) không? - Về cơ bản, bạn có kiểm tra giá trị trả về trước và chỉ sau đó giá trị
errno
? Hoặc có thểsend
đặterrno
trên mỗi cuộc gọi, giá trị trả lại bất kể? Điều đó sẽ làm cho việc kiểm tra lỗi dễ dàng hơn một chút ... - Nếu một người nhận được
EINTR
, hành vi mạnh mẽ, tốt cho một chương trình sẽ là gì? Chỉ cần ghi lại tiểu bang và thử lại vào dịp gửi tiếp theo, như vớiEWOULDBLOCK
vàEAGAIN
? - Bạn có kiểm tra cả hai
EWOULDBLOCK
vàEAGAIN
? Liệu chúng ta có thể tin tưởng cả hai có cùng giá trị, hay nó phụ thuộc vào việc thực hiện? - Có
send
trả lạiEMSGSIZE
cho ổ cắm luồng không? Nếu không, thì không có kích thước bộ đệm quá lớn, phải không? - Bản thân giá trị trả lại có thể bằng một trong các mã lỗi đã biết không?
Nếu bạn có thể cung cấp ví dụ về mã gửi không chặn mạnh mẽ, nó sẽ được đánh giá tuyệt đối.
gửi (2) có thể trả về 0 nếu số không được chuyển cho 'len'. Đối với một giao thức datagram như UDP, điều này thậm chí sẽ dẫn đến một gói zero-byte được gửi đi. Ngoài ra, errno không được bảo đảm không thay đổi trong suốt cuộc gọi thư viện thành công. – Anomie
@Anomie: phần đầu tiên là đủ, nhưng trong lần thứ hai, POSIX đảm bảo rằng một số cuộc gọi thư viện sẽ không sửa đổi errno nếu không có lỗi, và 'send' là một trong những cuộc gọi đó. –
Bạn thấy điều đó ở đâu? POSIX.1-2008 trực tuyến [tại đây] (http://pubs.opengroup.org/onlinepubs/9699919799/). [Trang trên errno] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/errno.html) nói "Cài đặt errno sau khi cuộc gọi thành công đến một hàm không được chỉ định trừ khi mô tả của hàm đó chỉ định rằng errno sẽ không được sửa đổi ", và [trang gửi] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html) dường như không nói bất kỳ điều gì như vậy. – Anomie