2010-06-08 16 views
6

Chúng tôi có một máy chủ ứng dụng đã được quan sát thấy gửi tiêu đề với kích thước cửa sổ TCP 0 vào những lúc mạng bị tắc nghẽn (tại trang của khách hàng).Ai đặt kích thước cửa sổ TCP xuống 0, Indy hoặc Windows?

Chúng tôi muốn biết nếu nó là Indy hoặc lớp Windows bên dưới có trách nhiệm điều chỉnh kích thước cửa sổ TCP xuống từ 64K danh nghĩa trong thích ứng với thông lượng có sẵn.
Và chúng tôi sẽ có thể hành động khi nó trở thành 0 (không có gì được gửi, người dùng chờ đợi => không tốt).

Vì vậy, mọi thông tin, liên kết, con trỏ đến mã Indy đều được chào đón ...

Tuyên bố từ chối trách nhiệm: Tôi không phải là chuyên gia mạng. Vui lòng giữ cho câu trả lời dễ hiểu đối với mức trung bình của tôi ;-)
Lưu ý: đó là Indy9/D2007 trên Windows Server 2003 SP2.

Chi tiết gory khác:
Trường hợp cửa sổ TCP zero xảy ra ở tầng giữa nói chuyện với máy chủ DB.
Điều này xảy ra cùng một lúc khi người dùng cuối phàn nàn về sự chậm trễ trong ứng dụng khách (đó là điều đã kích hoạt điều tra mạng).
2 vấn đề lớn về mạng gây ra tắc nghẽn đã được xác định.
Cửa sổ TCP zero đã xảy ra khi có sự tắc nghẽn mạng, nhưng có thể hoặc không thể do nó gây ra.
Chúng tôi muốn biết khi nào điều đó xảy ra và có cách để làm điều gì đó (ghi ít nhất) trong mã của chúng tôi.

Vì vậy, câu hỏi cốt lõi là ai đặt kích thước cửa sổ thành 0 và ở đâu?
Nơi để móc (trong Indy?) Để biết khi nào tình trạng đó xảy ra?

Trả lời

6

Kích thước cửa sổ trong tiêu đề TCP được noramlly đặt bởi phần mềm ngăn xếp TCP để phản ánh kích thước của vùng đệm sẵn có. Nếu máy chủ của bạn đang gửi gói với cửa sổ được đặt bằng 0, có thể do máy khách đang gửi dữ liệu nhanh hơn ứng dụng đang chạy trên máy chủ đang đọc nó và các bộ đệm liên quan đến kết nối TCP hiện đã đầy.

Đây là hoạt động hoàn toàn bình thường đối với giao thức TCP nếu máy khách gửi dữ liệu nhanh hơn máy chủ có thể đọc được. Khách hàng nên hạn chế gửi dữ liệu cho đến khi máy chủ gửi kích thước cửa sổ khác 0 (không có điểm nào vì nó sẽ bị hủy bỏ). Điều này có thể hoặc không thể phản ánh vấn đề nghiêm trọng giữa máy khách và máy chủ, nhưng nếu điều kiện vẫn tồn tại, có nghĩa là ứng dụng đang chạy trên máy chủ đã ngừng đọc dữ liệu nhận được (khi nó bắt đầu đọc, TCP và ngăn xếp TCP sẽ gửi một kích thước cửa sổ khác 0).

+0

Câu hỏi cốt lõi là ai đặt kích thước cửa sổ thành 0 và ở đâu? Đang cập nhật câu hỏi ... –

+3

Ngăn xếp TCP (trong trường hợp này là một phần của Windows Server) đặt kích thước cửa sổ bằng 0, nhưng nó thực hiện điều này vì ứng dụng đang chạy trên máy chủ (Indy?) Không đọc dữ liệu. –

+0

Do đó, nếu tầng giữa không thể gửi đến ứng dụng khách do tắc nghẽn mạng, nó dừng đọc dữ liệu đến từ máy chủ DB, sau đó làm cho hệ điều hành đặt kích thước cửa sổ tcp thành 0 ... và tất cả mọi người chờ đợi cho đến khi mọi thứ trở nên tốt hơn. Đúng? –

2

Tiêu đề TCP có kích thước cửa sổ bằng 0 cho biết bộ đệm của người nhận đã đầy. Đây là điều kiện bình thường đối với người viết nhanh hơn người đọc.

Khi đọc mô tả của bạn, không rõ nếu điều này là bất ngờ. Điều gì khiến bạn mở một trình phân tích giao thức?

+0

Một vài ở đây hoặc ở đó sẽ không có vẻ là một vấn đề, nhưng khi nó xảy ra, có như 40 trong cùng một giây. Cuộc điều tra đã được kích hoạt khi người dùng cuối phàn nàn về sự chậm lại đáng chú ý trong ứng dụng khách. 2 vấn đề chủ yếu được xác định ở cấp độ mạng có thể gây tắc nghẽn. Nhưng cửa sổ TCP zero có thể hoặc không thể do các điều kiện này gây ra, và dù sao chúng ta cũng muốn biết khi nào nó xảy ra và có thể ít nhất là ghi lại một số thông tin. –

2

Vì bạn có thể quan tâm đến một giải pháp cho vấn đề của bạn, quá:

Nếu bạn có một số kiểm soát trên những gì đang chạy trên phía máy chủ (một trong đó sẽ gửi các thông điệp kích thước 0 cửa sổ): Bạn có xem xét bằng cách sử dụng setsockopt() với SO_RCVBUF để tăng đáng kể kích thước của bộ đệm nhận của ổ cắm của bạn?

Trong Indy, setsockopt() là một phương thức của TIdSocketHandle. Bạn nên áp dụng nó cho tất cả các đối tượng TIdSocketHandle được kết hợp với ổ cắm của bạn. Và trong Indy 9, chúng được đặt thông qua Bindings thuộc tính trong TIdTCPServer của bạn.

Tôi đề nghị đầu tiên sử dụng getockopt() với SO_RCVBUF để xem những gì hệ điều hành cung cấp cho bạn dưới dạng kích thước bộ đệm mặc định. Sau đó tăng đáng kể điều này, có thể là các thử nghiệm liên tiếp, tăng gấp đôi kích thước mỗi lần. Bạn cũng có thể muốn chạy lại hàm getockopt() gọi sau setsockopt() để đảm bảo rằng bộ đếm của bạn đã thực sự được thực hiện: Thường có giới hạn trên mà việc triển khai socket đặt thành kích thước bộ đệm. Và trong trường hợp này, thường có một cách phụ thuộc vào hệ điều hành để di chuyển giá trị trần đó lên. Nhưng đó là những trường hợp khá khắc nghiệt, và bạn không có khả năng cần điều này.

Nếu bạn không có quyền kiểm soát mã nguồn ở bên bị tràn, chỉ cần kiểm tra xem phần mềm đang chạy ở đó có hiển thị một số tham số để thay đổi kích thước bộ đệm đó không.

Chúc may mắn!

+0

Cảm ơn bạn vì thông tin rất có giá trị này –

Các vấn đề liên quan