Tôi muốn biết nếu kịch bản sau là có thật không ?!select(), recv() và EWOULDBLOCK trên ổ cắm không chặn
- chọn() (RD) trên non-blocking socket TCP nói rằng các ổ cắm sẵn sàng
- sau recv() sẽ trở lại EWOULDBLOCK bất chấp những lời kêu gọi chọn()
Tôi muốn biết nếu kịch bản sau là có thật không ?!select(), recv() và EWOULDBLOCK trên ổ cắm không chặn
Tôi biết một lỗi trong một hành máy tính để bàn phổ biến nơi O_NONBLOCK
TCP socket, đặc biệt là những người đang chạy trên giao diện loopback, đôi khi có thể trở lại EAGAIN
từ recv()
sau select()
báo cáo ổ cắm sẵn sàng để đọc. Trong trường hợp của tôi, điều này xảy ra sau khi nửa bên kia đóng một nửa luồng gửi.
Để biết thêm chi tiết, hãy xem mã nguồn cho t_nx.ml
trong thư viện NX của phân phối Môi trường ứng dụng mạng OCaml của tôi. (link)
Có thể, nhưng chỉ trong một tình huống mà bạn có nhiều luồng/quy trình cố đọc từ cùng một socket.
Vui mừng khi nghe điều đó. Ứng dụng của tôi là đơn luồng nên tôi ổn. – mrvincenzo
Đối với recv()
bạn sẽ nhận được EAGAIN
thay vì EWOULDBLOCK
và có thể thực hiện được. Kể từ khi bạn vừa kiểm tra với select()
sau đó một trong hai điều xảy ra:
select()
và recv()
.Trong trường hợp hết thời gian chờ, chọn() trả về 0 để tôi không lo lắng về điều đó. – mrvincenzo
#define EWOULDBLOCK EAGAIN/* Thao tác sẽ chặn */- tìm thấy trên nhiều hệ điều hành – blaze
POSIX.1-2001 cho phép lỗi được trả lại khi đọc trên ổ cắm không chặn (và không yêu cầu chúng có cùng Giá trị.) –
Có thể trong môi trường đa luồng có hai chuỗi đang đọc từ ổ cắm. Đây có phải là ứng dụng đa luồng không?
Đây là một ứng dụng đơn luồng. – mrvincenzo
Thậm chí nếu có một thời gian chờ trên socket thay vì chỉ là một tham số để 'select()'? Nếu thời gian chờ xảy ra giữa 'select()' và 'recv()' thì sao? – dwc
Trong trường hợp này, bạn sẽ không thấy hành vi này. – mikelong
Nếu bạn không gọi bất kỳ syscall nào khác giữa select() và recv() trên socket này, thì recv() sẽ không bao giờ trả về EAGAIN hoặc EWOULDBLOCK.
Tôi không biết ý nghĩa của chúng với thời gian chờ rút lại, tuy nhiên, tiêu chuẩn POSIX không đề cập đến nó ở đây để bạn có thể gọi recv an toàn().
Mặc dù ứng dụng của tôi là một ứng dụng đơn luồng, tôi nhận thấy rằng hành vi được mô tả không phải là hiếm trong RHEL5. Cả hai với các cổng TCP và UDP được đặt thành O_NONBLOCK (tùy chọn socket duy nhất được thiết lập). select() báo cáo rằng socket đã sẵn sàng nhưng recv() trả về EAGAIN.
Trên Linux, nó thậm chí còn được ghi nhận rằng điều này có thể xảy ra, khi tôi đọc nó.
Xem câu hỏi này:
Liên kết dường như bị hỏng – Thomas
Vui nhộn, trong trình đơn chỉnh sửa, có thể nhấp. : D – thejh