2011-01-11 42 views
10

Tôi hơi bối rối về hành vi của QTcpSocket::waitForBytesWritten() ...Hành vi của QTcpSocket :: waitForBytesWritten?

Cho đến khi nào chức năng này chặn?

  • Cho đến khi dữ liệu được ghi vào bộ đệm trong của hệ điều hành để truyền qua TCP?
  • Cho đến khi dữ liệu được chuyển đổi vật lý thành gói TCP và được gửi?
  • Cho đến khi toàn bộ dữ liệu được truyền và máy khách từ xa thừa nhận rằng tất cả các gói đã được nhận?

Tôi đã xem tài liệu, nhưng dường như không rõ ràng lắm.

Trả lời

7

Nói chung các hệ điều hành chỉ cung cấp API dễ dàng cho câu hỏi đầu tiên - vì Qt là một API di động, tốt nhất nên chỉ dựa vào nó là chuyển sang bộ đệm của hệ điều hành. Nếu bạn cần một sự thừa nhận thực sự về việc nhận, tốt nhất là nó sẽ được ứng dụng từ xa gửi đi - sau khi tất cả, dữ liệu có thể được điều khiển từ xa nhưng không bao giờ đọc bộ đệm đọc của hệ điều hành từ xa.

Nếu bạn cần tránh việc chặn bên từ xa mãi mãi, bạn nên đợi tín hiệu QIODevice::bytesWritten và quay lại vòng lặp sự kiện để thực hiện công việc khác hoặc chỉ cần đặt thời gian chờ phù hợp. Nói chung, phía từ xa luôn có thể chặn bạn ở một mức nào đó - nghĩa là nó có thể từ chối ack, làm đầy bộ đệm hệ điều hành cục bộ của bạn, tại thời điểm đó ghi sẽ không làm cho nó từ Qt đến hệ điều hành; không có vấn đề gì cấp waitForBytesWritten() là tại, nó luôn luôn có thể bị chặn.

Như vậy, bytesWrittenwaitForBytesWritten() chỉ nên được sử dụng để điều tiết nguồn gốc của dữ liệu - ví dụ, nếu bạn đã đi vào một vòng lặp chặt chẽ thông qua 1G dữ liệu vào ổ cắm cùng một lúc, bạn có thể kết thúc đệm nó trong quá trình và hết bộ nhớ. Bằng cách kích hoạt các lần đọc/ghi bổ sung với tín hiệu bytesWritten, bạn có thể tránh vấn đề này.

+0

Tôi không cần xác nhận đã nhận. Điều tôi thực sự * muốn là tránh tình huống mà một khách hàng có thể trì hoãn ứng dụng bằng cách đợi để gửi ACK. –

+1

@George: Đã cập nhật câu trả lời :) – bdonlan