2010-10-13 15 views
13

Một số khác trong saga liên tục của bản thân mình so với Boost.Asio ...Boost.Asio: Operation hủy vào async_read

Tôi có một khách hàng không đồng bộ đơn giản và máy chủ sử dụng async_write và async_read để giao tiếp. Máy khách có thể ghi thành công các byte vào socket, nhưng máy chủ không bao giờ thấy chúng; trình xử lý đọc của tôi trên máy chủ bị lỗi với "Đã hủy thao tác".

Tôi có xu hướng tin rằng đây có thể là vấn đề thời gian với khách hàng ghi dữ liệu sau máy chủ đã cố gắng đọc và không thành công, nhưng tôi đã nghĩ rằng dữ liệu sẽ đợi trên ổ cắm (trừ khi ổ cắm đã bị đóng trong thời gian chờ đợi).

Để kiểm tra điều này tôi chỉ đơn giản tái chạy các hoạt động đọc trong xử lý lỗi, ví dụ:

read_handler() 
{ 
    if (!error) { 
     /* bytes read */ 
    } else { 
     async_read(socket, buffer, read_handler) 
    } 
} 

Nhưng tất cả điều này đã cho tôi là một segfault trong pthread_mutex_lock qua một cuộc gọi đến async_receive.

Bất cứ ai có thể chỉ cho tôi theo hướng của bất kỳ thông tin liên quan nào (hoặc, tốt hơn, hãy cho tôi biết chính xác những gì tôi đang làm sai;))?

CẬP NHẬT: Máy chủ và máy khách dựa trên ví dụ về máy chủ trò chuyện trong tài liệu Asio, với máy khách và máy chủ đều chạy trong cùng một quá trình (có thể đây là vấn đề không? cùng io_service ...); cả hai đều không đồng bộ và sử dụng Boost 1.44.0. Tôi đang làm việc trên OS X nhưng điều này cũng có thể tái tạo trên Linux.

CẬP NHẬT II: Linh hoạt của tôi là chính xác và nếu máy chủ và máy khách được cung cấp các đối tượng io_service riêng biệt thì async_read sẽ thấy các byte trên socket. Điều này vẫn cung cấp cho một segfault trong boost::asio::detail::kqueue_reactor::post_immediate_completion mà dường như xuất phát từ io_service.run(). Trước khi tôi đi xa hơn nữa, đang sử dụng các đối tượng riêng biệt io_service đúng cách?

+0

Những nền tảng mà bạn đang chạy trên? –

+0

Nền tảng là OSX và Linux; cả hai đều thể hiện cùng một vấn đề. – kfb

+0

Tôi nghĩ rằng chúng tôi cần xem thêm một chút mã của bạn để có cơ hội đoán được những gì bạn đã làm sai! Nó cũng sẽ giúp để biết một cái gì đó về thiết lập của bạn - là khách hàng và máy chủ chạy trên cùng một máy hoặc khác nhau, ví dụ? Cả hai đều được viết bằng cách sử dụng boost :: asio? Phiên bản Boost nào bạn đang sử dụng (asio đã thay đổi một chút gần đây)? – dajames

Trả lời

25

Thao tác bị hủy (mã lỗi hoạt động_aborted) được gửi khi ổ cắm là closed hoặc bị hủy.

Rất có thể kết nối của bạn sắp hết phạm vi.

Có thể vì nó đã xảy ra với tôi, bạn quên đính kèm async_handlers vào con trỏ shared_from_this(). I.e. Bạn nên gắn bộ xử lý của bạn như thế này:

async_read(m_socket, 
      boost::asio::buffer((void*)m_buffer, m_header_size), 
      boost::bind(&TcpConnection::handleRead, 
      shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 

KHÔNG như thế này:

async_read(m_socket, 
      boost::asio::buffer((void*)m_buffer, m_header_size), 
      boost::bind(&TcpConnection::handleRead, 
      this, //<- This will go out of scope and the socket will be closed 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
+2

Cảm ơn, tôi đã gặp sự cố ở một vùng hoàn toàn khác, nhưng cũng có thông báo lỗi 'Thao tác bị hủy'. Và đó là một 'điều này' đã đi ra khỏi phạm vi! Rất may tôi đã tìm thấy câu trả lời của bạn sau khi gỡ lỗi nó trong nhiều giờ ... – Chris

+0

đó là câu trả lời lớn nhất của tất cả chúng. lỗi hoàn toàn lạ. chẩn đoán hoàn toàn tại chỗ trên. – Alex

+0

và tại sao chính xác là kết nối ngoài phạm vi, khi điều này được thông qua? – bryanph