diff --git a/include/boost/asio/detail/reactive_socket_service.hpp b/include/boost/asio/detail/reactive_socket_service.hpp index 46ce9cdc..d474ae79 100644 --- a/include/boost/asio/detail/reactive_socket_service.hpp +++ b/include/boost/asio/detail/reactive_socket_service.hpp @@ -1004,7 +1004,7 @@ public: return bytes_recvd; // Check for EOF. - if (bytes_recvd == 0) + if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) { ec = boost::asio::error::eof; return 0; @@ -1043,11 +1043,13 @@ public: public handler_base_from_member { public: - receive_operation(socket_type socket, boost::asio::io_service& io_service, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler handler) + receive_operation(socket_type socket, int protocol_type, + boost::asio::io_service& io_service, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler handler) : handler_base_from_member(handler), socket_(socket), + protocol_type_(protocol_type), io_service_(io_service), work_(io_service), buffers_(buffers), @@ -1080,7 +1082,7 @@ public: // Receive some data. int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec); - if (bytes == 0) + if (bytes == 0 && protocol_type_ == SOCK_STREAM) ec = boost::asio::error::eof; // Check if we need to run the operation again. @@ -1100,6 +1102,7 @@ public: private: socket_type socket_; + int protocol_type_; boost::asio::io_service& io_service_; boost::asio::io_service::work work_; MutableBufferSequence buffers_; @@ -1159,13 +1162,15 @@ public: { reactor_.start_except_op(impl.socket_, impl.reactor_data_, receive_operation( - impl.socket_, this->get_io_service(), buffers, flags, handler)); + impl.socket_, impl.protocol_.type(), + this->get_io_service(), buffers, flags, handler)); } else { reactor_.start_read_op(impl.socket_, impl.reactor_data_, receive_operation( - impl.socket_, this->get_io_service(), buffers, flags, handler)); + impl.socket_, impl.protocol_.type(), + this->get_io_service(), buffers, flags, handler)); } } } @@ -1248,7 +1253,7 @@ public: } // Check for EOF. - if (bytes_recvd == 0) + if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM) { ec = boost::asio::error::eof; return 0; @@ -1291,12 +1296,13 @@ public: public handler_base_from_member { public: - receive_from_operation(socket_type socket, + receive_from_operation(socket_type socket, int protocol_type, boost::asio::io_service& io_service, const MutableBufferSequence& buffers, endpoint_type& endpoint, socket_base::message_flags flags, Handler handler) : handler_base_from_member(handler), socket_(socket), + protocol_type_(protocol_type), io_service_(io_service), work_(io_service), buffers_(buffers), @@ -1332,7 +1338,7 @@ public: std::size_t addr_len = sender_endpoint_.capacity(); int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_, sender_endpoint_.data(), &addr_len, ec); - if (bytes == 0) + if (bytes == 0 && protocol_type_ == SOCK_STREAM) ec = boost::asio::error::eof; // Check if we need to run the operation again. @@ -1353,6 +1359,7 @@ public: private: socket_type socket_; + int protocol_type_; boost::asio::io_service& io_service_; boost::asio::io_service::work work_; MutableBufferSequence buffers_; @@ -1390,8 +1397,8 @@ public: reactor_.start_read_op(impl.socket_, impl.reactor_data_, receive_from_operation( - impl.socket_, this->get_io_service(), buffers, - sender_endpoint, flags, handler)); + impl.socket_, impl.protocol_.type(), this->get_io_service(), + buffers, sender_endpoint, flags, handler)); } } diff --git a/include/boost/asio/detail/win_iocp_socket_service.hpp b/include/boost/asio/detail/win_iocp_socket_service.hpp index 3b6322bf..1c0ca1bc 100644 --- a/include/boost/asio/detail/win_iocp_socket_service.hpp +++ b/include/boost/asio/detail/win_iocp_socket_service.hpp @@ -1236,7 +1236,7 @@ public: boost::asio::error::get_system_category()); return 0; } - if (bytes_transferred == 0) + if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) { ec = boost::asio::error::eof; return 0; @@ -1267,7 +1267,7 @@ public: : public operation { public: - receive_operation(win_iocp_io_service& io_service, + receive_operation(int protocol_type, win_iocp_io_service& io_service, weak_cancel_token_type cancel_token, const MutableBufferSequence& buffers, Handler handler) : operation(io_service, @@ -1275,6 +1275,7 @@ public: MutableBufferSequence, Handler>::do_completion_impl, &receive_operation< MutableBufferSequence, Handler>::destroy_impl), + protocol_type_(protocol_type), work_(io_service.get_io_service()), cancel_token_(cancel_token), buffers_(buffers), @@ -1323,6 +1324,7 @@ public: // Check for connection closed. else if (!ec && bytes_transferred == 0 + && handler_op->protocol_type_ == SOCK_STREAM && !boost::is_same::value) { ec = boost::asio::error::eof; @@ -1359,6 +1361,7 @@ public: ptr.reset(); } + int protocol_type_; boost::asio::io_service::work work_; weak_cancel_token_type cancel_token_; MutableBufferSequence buffers_; @@ -1391,8 +1394,9 @@ public: typedef receive_operation value_type; typedef handler_alloc_traits alloc_traits; raw_handler_ptr raw_ptr(handler); - handler_ptr ptr(raw_ptr, iocp_service_, - impl.cancel_token_, buffers, handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, protocol_type, + iocp_service_, impl.cancel_token_, buffers, handler); // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers]; @@ -1465,8 +1469,9 @@ public: typedef receive_operation value_type; typedef handler_alloc_traits alloc_traits; raw_handler_ptr raw_ptr(handler); - handler_ptr ptr(raw_ptr, iocp_service_, - impl.cancel_token_, buffers, handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, protocol_type, + iocp_service_, impl.cancel_token_, buffers, handler); // Issue a receive operation with an empty buffer. ::WSABUF buf = { 0, 0 }; @@ -1557,7 +1562,7 @@ public: boost::asio::error::get_system_category()); return 0; } - if (bytes_transferred == 0) + if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM) { ec = boost::asio::error::eof; return 0; @@ -1594,7 +1599,7 @@ public: : public operation { public: - receive_from_operation(win_iocp_io_service& io_service, + receive_from_operation(int protocol_type, win_iocp_io_service& io_service, endpoint_type& endpoint, const MutableBufferSequence& buffers, Handler handler) : operation(io_service, @@ -1602,6 +1607,7 @@ public: MutableBufferSequence, Handler>::do_completion_impl, &receive_from_operation< MutableBufferSequence, Handler>::destroy_impl), + protocol_type_(protocol_type), endpoint_(endpoint), endpoint_size_(static_cast(endpoint.capacity())), work_(io_service.get_io_service()), @@ -1648,7 +1654,8 @@ public: } // Check for connection closed. - if (!ec && bytes_transferred == 0) + if (!ec && bytes_transferred == 0 + && handler_op->protocol_type_ == SOCK_STREAM) { ec = boost::asio::error::eof; } @@ -1687,6 +1694,7 @@ public: ptr.reset(); } + int protocol_type_; endpoint_type& endpoint_; int endpoint_size_; boost::asio::io_service::work work_; @@ -1721,8 +1729,9 @@ public: typedef receive_from_operation value_type; typedef handler_alloc_traits alloc_traits; raw_handler_ptr raw_ptr(handler); - handler_ptr ptr(raw_ptr, iocp_service_, - sender_endp, buffers, handler); + int protocol_type = impl.protocol_.type(); + handler_ptr ptr(raw_ptr, protocol_type, + iocp_service_, sender_endp, buffers, handler); // Copy buffers into WSABUF array. ::WSABUF bufs[max_buffers];