मैं बूस्ट लाइब्रेरीज़ (एएसआईओ) का उपयोग करके केवल यूडीपी सॉकेट से डेटा प्राप्त करने के लिए समर्पित एक स्वायत्त धागा बनाना चाहता हूं। यह थ्रेड यूडीपी सॉकेट से प्राप्त कुछ डेटा द्वारा ट्रिगर किया गया एक अनंत लूप होना चाहिए। मेरे आवेदन में मुझे एक एसिंक्रोनस प्राप्त ऑपरेशन का उपयोग करने की आवश्यकता है।बूस्ट asio udp सॉकेट async_receive_from हैंडलर को कॉल नहीं करता
यदि मैं सिंक्रोनस फ़ंक्शन का उपयोग करता हूं तो सब कुछ अपेक्षित काम करता है।
हालांकि अगर मैं हैंडलर से async_receive_from का उपयोग कभी नहीं करता हूं। चूंकि मैं यह पता लगाने के लिए एक सेमफोर का उपयोग करता हूं कि कुछ डेटा प्राप्त हुए हैं, प्रोग्राम लॉक और लूप कभी ट्रिगर नहीं होता है।
मैंने सत्यापित किया है (एक नेटवर्क विश्लेषक के साथ) कि प्रेषक डिवाइस यूडीपी सॉकेट पर डेटा भेजता है।
मैंने निम्नलिखित कोड में समस्या को अलग कर दिया है।
#include <boost\array.hpp>
#include <boost\asio.hpp>
#include <boost\thread.hpp>
#include <boost\interprocess\sync\interprocess_semaphore.hpp>
#include <iostream>
typedef boost::interprocess::interprocess_semaphore Semaphore;
using namespace boost::asio::ip;
class ReceiveUDP
{
public:
boost::thread* m_pThread;
boost::asio::io_service m_io_service;
udp::endpoint m_local_endpoint;
udp::endpoint m_sender_endpoint;
udp::socket m_socket;
size_t m_read_bytes;
Semaphore m_receive_semaphore;
ReceiveUDP() :
m_socket(m_io_service),
m_local_endpoint(boost::asio::ip::address::from_string("192.168.0.254"), 11),
m_sender_endpoint(boost::asio::ip::address::from_string("192.168.0.11"), 5550),
m_receive_semaphore(0)
{
Start();
}
void Start()
{
m_pThread = new boost::thread(&ReceiveUDP::_ThreadFunction, this);
}
void _HandleReceiveFrom(
const boost::system::error_code& error,
size_t received_bytes)
{
m_receive_semaphore.post();
m_read_bytes = received_bytes;
}
void _ThreadFunction()
{
try
{
boost::array<char, 100> recv_buf;
m_socket.open(udp::v4());
m_socket.bind(m_local_endpoint);
m_io_service.run();
while (1)
{
#if 1 // THIS WORKS
m_read_bytes = m_socket.receive_from(
boost::asio::buffer(recv_buf), m_sender_endpoint);
#else // THIS DOESN'T WORK
m_socket.async_receive_from(
boost::asio::buffer(recv_buf),
m_sender_endpoint,
boost::bind(&ReceiveUDP::_HandleReceiveFrom, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
/* The program locks on this wait since _HandleReceiveFrom
is never called. */
m_receive_semaphore.wait();
#endif
std::cout.write(recv_buf.data(), m_read_bytes);
}
m_socket.close();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
};
void main()
{
ReceiveUDP receive_thread;
receive_thread.m_pThread->join();
}
सेमाफोर पर एक timed_wait लेकिन डिबग प्रयोजनों के लिए मैं ऊपर कोड में के रूप में एक अवरुद्ध इंतजार का इस्तेमाल किया है, पसंद किया जा रहा है।
क्या मुझे कुछ याद आया? मेरी गलती कहां है?
बहुत बहुत धन्यवाद! मैंने आपके सुझावों के अनुसार कोड को संशोधित किया है और सब कुछ ठीक काम करता है। मैंने थ्रेड निर्माण से पहले आईओ सेवा को कॉन्फ़िगर किया है। कॉल io_service.run करने के लिए() सिर्फ धागा निर्माण के बाद है: \t शून्य प्रारंभ() \t { \t \t m_socket.open (यूडीपी :: v4()); \t \t m_socket.bind (m_local_endpoint); \t \t StartRead(); \t \t m_pThread = नया बढ़ावा :: थ्रेड (और ReceiveUDP :: _ थ्रेड फ़ंक्शन, यह); \t \t m_io_service.run(); \t} जहां StartRead() async_receive_from पर कॉल है। फिर से धन्यवाद। – arms
इसके लिए धन्यवाद, मैं पागल हो रहा था। – Alex