Một ghi trên Ổ cắm cũng có thể chặn, đặc biệt nếu đó là một Ổ cắm TCP. Hệ điều hành sẽ chỉ đệm một lượng dữ liệu chưa được truyền đi (hoặc được truyền nhưng chưa được nhận). Nếu bạn viết nội dung nhanh hơn ứng dụng từ xa có thể đọc nó, cuối cùng ổ cắm sẽ sao lưu và các cuộc gọi write
của bạn sẽ bị chặn.
Đối phó với những câu hỏi của followup:
Vậy là có một cơ chế để thiết lập một thời gian chờ cho việc này? Tôi không chắc chắn hành vi của mà nó có ... có thể vứt bỏ dữ liệu nếu bộ đệm đầy? Hoặc có thể xóa dữ liệu cũ hơn trong bộ đệm?
Không có cơ chế để đặt thời gian chờ ghi trên java.net.Socket. Có phương thức Socket.setSoTimeout()
, nhưng nó ảnh hưởng đến các cuộc gọi accept()
và read()
cuộc gọi ... và không phải write()
cuộc gọi. Rõ ràng, bạn có thể ghi thời gian chờ nếu bạn sử dụng NIO, chế độ không chặn và Bộ chọn, nhưng điều này không hữu ích như bạn có thể tưởng tượng.
Ngăn xếp TCP được triển khai đúng cách không loại bỏ dữ liệu đệm trừ khi kết nối được đóng. Tuy nhiên, khi bạn nhận được một thời gian chờ ghi, nó là không chắc chắn liệu dữ liệu hiện đang trong bộ đệm cấp độ hệ điều hành đã được nhận bởi đầu kia ... hay không. Vấn đề khác là bạn không biết bao nhiêu dữ liệu từ write
cuối cùng của bạn đã thực sự được chuyển sang bộ đệm ngăn xếp TCP cấp hệ điều hành. Không có một số giao thức cấp ứng dụng để đồng bộ hóa lại luồng *, điều duy nhất an toàn để thực hiện sau khi hết thời gian chờ trên write
là tắt kết nối.
Ngược lại, nếu bạn sử dụng ổ cắm UDP, các cuộc gọi write()
sẽ không chặn trong bất kỳ khoảng thời gian đáng kể nào. Nhưng nhược điểm là nếu có vấn đề về mạng hoặc ứng dụng từ xa không được cập nhật, tin nhắn sẽ bị xóa trên sàn mà không có thông báo kết thúc. Ngoài ra, bạn có thể thấy rằng các thư đôi khi được gửi tới ứng dụng từ xa không đúng thứ tự. Nó sẽ tùy thuộc vào bạn (nhà phát triển) để đối phó với những vấn đề này.
* Về mặt lý thuyết có thể thực hiện điều này, nhưng đối với hầu hết các ứng dụng, sẽ không có ý nghĩa để thực hiện thêm cơ chế đồng bộ hóa trên đầu luồng TCP/IP đã tin cậy (tới một điểm). Và nếu nó có ý nghĩa, bạn cũng sẽ cần phải đối phó với khả năng kết nối đóng lại ... vì vậy nó sẽ đơn giản hơn để giả sử nó đóng.
Nguồn
2009-08-27 05:04:31
Thực tế là có không phải là một tính năng thời gian chờ bản thân nó không là một dấu hiệu cho thấy nó không chặn. Một dấu hiệu cho thấy nó là thiếu giá trị trả về: nếu nó không chặn, tại sao nó không trả về số byte thực sự được viết? Một dấu hiệu khác được đưa ra bởi chỉ cần thử nó. – EJP