Nguyên nhân nào gây ra lỗi vỡ đường ống?


83

Tôi biết rằng lỗi đường ống bị hỏng xảy ra khi ổ cắm ở phía đồng đẳng bị đóng.

Tuy nhiên, trong thử nghiệm của tôi, tôi đã lưu ý rằng một cuộc gọi 'gửi' ngay lập tức ở phía này khi phía ngang hàng đang đóng không phải lúc nào cũng dẫn đến lỗi đường ống bị hỏng.

Ví dụ:

Sau khi đóng ổ cắm ở phía ngang hàng (tôi đã thử đóng sạch bằng cách gọi đóng và cũng đóng bất thường bằng cách giết ngang hàng), nếu tôi cố gắng gửi 40 byte, thì tôi không nhận được đường ống bị hỏng, nhưng, nếu tôi cố gắng gửi 40000 byte sau đó nó ngay lập tức báo lỗi đường ống bị hỏng.

Chính xác thì nguyên nhân nào khiến đường ống bị vỡ và hành vi của nó có thể dự đoán được không?

Câu trả lời:


59

Có thể mất thời gian để quan sát mạng đóng - tổng thời gian trên danh nghĩa là khoảng 2 phút (vâng, vài phút!) Sau khi đóng trước khi các gói dành cho cổng được cho là đã chết. Điều kiện lỗi được phát hiện tại một số điểm. Với một chữ viết nhỏ, bạn đang ở bên trong MTU của hệ thống, vì vậy tin nhắn được xếp hàng đợi để gửi. Với một ghi lớn, bạn lớn hơn MTU và hệ thống phát hiện ra vấn đề nhanh hơn. Nếu bạn bỏ qua tín hiệu SIGPIPE, thì các chức năng sẽ trả về lỗi EPIPE trên một đường ống bị hỏng - tại một số điểm khi phát hiện thấy sự cố kết nối bị hỏng.


4
@varevarao: Tôi không nghĩ rằng việc xếp hàng đợi truyền và gửi trong các khoảng thời gian cụ thể là một giải pháp. Xếp hàng đợi truyền cho đến khi có nhiều hơn MTU để gửi có thể là một giải pháp thay thế nếu ứng dụng của bạn có thể sống chung với sự chậm trễ.
Jonathan Leffler

11

Trạng thái hiện tại của một ổ cắm được xác định bởi hoạt động 'duy trì sự sống'. Trong trường hợp của bạn, điều này có thể xảy ra khi bạn đang thực hiện sendcuộc gọi, keep-alivehoạt động thông báo rằng ổ cắm đang hoạt động và vì vậy sendcuộc gọi sẽ ghi dữ liệu cần thiết (40 byte) vào bộ đệm và trả về mà không đưa ra bất kỳ lỗi nào.

Khi bạn đang gửi một đoạn lớn hơn, cuộc gọi gửi sẽ chuyển sang trạng thái chặn.

Trang send man cũng xác nhận điều này:

Khi tin nhắn không vừa với bộ đệm gửi của ổ cắm, send () thường chặn, trừ khi ổ cắm được đặt ở chế độ I / O không chặn. Trong chế độ không chặn, nó sẽ trả về EAGAIN trong trường hợp này

Vì vậy, trong khi chặn bộ đệm có sẵn miễn phí, nếu người gọi được thông báo (bằng cơ chế duy trì hoạt động) rằng đầu bên kia không còn nữa, thì cuộc gọi gửi sẽ không thành công.

Việc dự đoán kịch bản chính xác là rất khó với những thông tin được đề cập, nhưng tôi tin rằng, đây sẽ là lý do khiến bạn gặp vấn đề.


1
Trạng thái hiện tại của ổ cắm được quan sát bởi hoạt động ACK. Keepalive chỉ là một hoạt động ACK nguồn nhỏ và nó bị tắt theo mặc định.
Marquis of Lorne

3

Có thể 40 byte vừa với bộ đệm đường ống, còn 40000 byte thì không?

Biên tập:

Quá trình gửi được gửi một tín hiệu SIGPIPE khi bạn cố gắng ghi vào một đường ống đã đóng. Tôi không biết chính xác khi nào tín hiệu được gửi đi hoặc bộ đệm đường ống có ảnh hưởng gì đến việc này. Bạn có thể khôi phục bằng cách bẫy tín hiệu với cuộc gọi sigaction.


0

Khi đóng ngang hàng, bạn sẽ không biết liệu nó chỉ dừng gửi hay cả gửi và nhận. Bởi vì TCP cho phép điều này, btw, bạn nên biết sự khác biệt giữa đóng và tắt. Nếu ngang hàng ngừng gửi và nhận, trước tiên bạn gửi một số byte, nó sẽ thành công. Nhưng hạt nhân ngang hàng sẽ gửi cho bạn RST. Vì vậy, sau đó bạn gửi một số byte, hạt nhân của bạn sẽ gửi cho bạn tín hiệu SIGPIPE, nếu bạn bắt hoặc bỏ qua tín hiệu này, khi gửi trả về, bạn sẽ gặp lỗi Đường ống bị hỏng hoặc nếu không, hành vi mặc định của chương trình của bạn đang bị lỗi .


-1

Chúng tôi gặp lỗi Broken Pipe sau khi mạng mới được đưa vào. Sau khi đảm bảo rằng cổng 9100 đã mở và có thể kết nối với máy in qua cổng telnet 9100, chúng tôi đã thay đổi trình điều khiển máy in từ "HP" thành "Generic PDF", lỗi đường ống bị hỏng đã biến mất và có thể in thành công.

(RHEL 7, Máy in nhãn hiệu Ricoh, cấu hình HP đã có sẵn và hoạt động trên mạng trước đó)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.