2009-08-03 23 views
10

Tôi đã đọc tài liệu tham khảo asio tăng cường, xem qua hướng dẫn và xem xét một số ví dụ. Tuy nhiên, tôi không thể thấy cách tháo dỡ ổ cắm:Làm thế nào nên một giọt nước mắt xuống một tăng :: asio :: ip :: udp :: socket?

  1. Tôi có nên gọi close() hoặc được thực hiện bởi bộ hủy của ổ cắm?
  2. Khi nào tôi nên gọi tắt máy()
  3. Hiệu ứng tắt máy() là gì? Tôi biết rằng "Vô hiệu hóa gửi hoặc nhận", nhưng cách thực hiện điều này? Tôi có thể mong đợi điều gì nếu tôi gửi hoặc nhận bằng cách sử dụng ổ cắm sau khi nó đã bị vô hiệu hóa?
  4. Những lỗi tôi có thể mong đợi từ gần()

Trả lời

10

Vì đây là một câu hỏi đa, tôi sẽ làm hết sức mình để trả lời từng phần để sự hài lòng của bạn:

1) Đó là kinh nghiệm của tôi với ASIO ổ cắm mà destructor xử lý đóng socket. Tuy nhiên, tôi chỉ xử lý các socket TCP. Cách tốt nhất để kiểm tra điều này là chỉ cần nhìn vào mã cho destructor để xem nó có làm bất cứ điều gì tương tự như một đóng. Tôi biết rằng mã Boost có thể hơi phức tạp để đi qua, vì vậy có thể dễ dàng nhất là chỉ cần tạo một chương trình mẫu nhỏ mở ổ cắm UDP và sau đó phá hủy nó. Bằng cách đó bạn có thể bước qua mã trong một trình gỡ lỗi để theo logic.

Vì các nhà thiết kế của Boost đã tính đến các ổ cắm TCP, tôi có một thời gian khó tưởng tượng rằng chúng sẽ không làm tương tự cho các ổ cắm UDP.

2) Gọi shutdown() chỉ khi bạn cảm thấy cần thiết để ngăn chặn bất kỳ mã nào hoạt động trong tương lai recv và/hoặc send trên ổ cắm. Nó không thường được yêu cầu, mặc dù tôi đã nhìn thấy nó được sử dụng trên ổ cắm TCP để buộc các ổ cắm để gửi một RST khi nó được đóng (trái ngược với mặc định "duyên dáng" tắt máy trong khi chờ xử lý gửi được xử lý).

3) Bạn có thể nghĩ rằng ổ cắm là một hình thức liên lạc hai kênh: một để đọc, một cho việc gửi. Bạn có thể tắt hoặc là độc lập với nhau và bạn có thể tiếp tục sử dụng một kênh khi kênh kia tắt (tức là bạn vẫn có thể nhận được sau khi tắt để gửi và ngược lại). Đóng socket là giống hệt với việc tắt máy gọi trên cả recv và send.

Tắt cho recv chỉ đơn giản là ngăn không cho mã của bạn đọc thêm dữ liệu nữa. Nếu bạn cố gắng làm như vậy, bạn sẽ gặp lỗi ổ cắm. Tương tự như vậy, nếu phía bên kia của kết nối cố gắng gửi dữ liệu cho bạn, nó sẽ nhận được một lỗi (xin lỗi để chuyển sang thế giới TCP một lần nữa, nhưng tôi tin rằng RST được trả lời lại cho người gửi).

Tắt để gửi tương tự, ngăn mã của bạn gửi bất kỳ dữ liệu nào khác. Nếu bộ nhớ phục vụ cho tôi một cách chính xác, điều này trông giống như những gì xảy ra khi bạn đóng một ổ cắm (một gói tin có chiều dài bằng không được gửi qua để báo hiệu phía bên kia là kênh cụ thể đã bị tắt). Mọi nỗ lực gửi trong tương lai sẽ trả về lỗi.

4) Bạn sẽ phải kiểm tra tài liệu của mình để biết chắc chắn. MSDN sẽ cung cấp cho bạn một dấu hiệu khá tốt, mặc dù tôi không biết rằng tôi muốn xem xét nó là độc quyền.

+0

Cảm ơn, tôi đã tìm ra một số những điều này, nhưng tôi vẫn không chắc liệu close() thực sự được gọi là trong destructor của socket. Những gì tôi thực sự đã không grok'ed là kết nối chặt chẽ giữa asio tăng và lập trình mạng truyền thống. Cả hai giải thích của bạn tắt máy() và gợi ý để xem xét các mã lỗi socket msdn cho thấy điều này. +1 – Torleif

+0

Vui vì tôi có thể giúp :) – Brian

+0

FWIW, gọi .shutdown (BOTH) trên ổ cắm UDP hoạt động trên Windows, nhưng sẽ bị lỗi khi sử dụng ổ cắm. –

1

Từ các ví dụ được đưa ra tại trang web Boost, có vẻ như bạn chỉ nên sử dụng close().Ví dụ, nhìn vào cái này:

 
void connection::stop() 
{ 
    socket_.close(); 
} 

Taken từ địa chỉ này: HTTP Server

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