Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ tcp通信线程_C++_Multithreading_Tcp_Boost Asio - Fatal编程技术网

C++ tcp通信线程

C++ tcp通信线程,c++,multithreading,tcp,boost-asio,C++,Multithreading,Tcp,Boost Asio,我的问题是关于线程的使用。我正在制作一个通过TCP/IP连接到设备的应用程序。我正在使用boost::asio lib。我已经决定使用一个读或听线程和一个写线程来分别听和写设备。我的困惑是,创建处理通信的套接字的函数是否也应该是线程。 谢谢:)这取决于你是否想同时读写。在这种情况下,您将需要一个线程用于读取,一个线程用于写入,但您必须正确地同步这些线程,以防设备中的两个流彼此有关联(它们可能会这样做)。然而,在我看来,与设备通话就像是一项任务,您可以建立连接,发送一些请求,等待并阅读答案,发送另

我的问题是关于线程的使用。我正在制作一个通过TCP/IP连接到设备的应用程序。我正在使用boost::asio lib。我已经决定使用一个读或听线程和一个写线程来分别听和写设备。我的困惑是,创建处理通信的套接字的函数是否也应该是线程。
谢谢:)

这取决于你是否想同时读写。在这种情况下,您将需要一个线程用于读取,一个线程用于写入,但您必须正确地同步这些线程,以防设备中的两个流彼此有关联(它们可能会这样做)。然而,在我看来,与设备通话就像是一项任务,您可以建立连接,发送一些请求,等待并阅读答案,发送另一个请求,等待并阅读下一个答案,等等。在这种情况下,只需使用一个线程就足够了,并且可以让您的生活更加轻松。

在我的客户端类中,我创建了两个工作线程来处理发送和接收消息,这些消息用于多个服务器的多个连接。创建这两个工作线程的线程恰好是用户界面线程。这就是我的代码的样子:

// Create the resolver and query objects to resolve the host name in serverPath to an ip address.
boost::asio::ip::tcp::resolver resolver(*IOService);
boost::asio::ip::tcp::resolver::query query(serverPath, port);
boost::asio::ip::tcp::resolver::iterator EndpointIterator = resolver.resolve(query);
// Set up an SSL context.
boost::asio::ssl::context ctx(*IOService, boost::asio::ssl::context::tlsv1_client);
// Specify to not verify the server certificiate right now.
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
// Init the socket object used to initially communicate with the server.
pSocket = new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(*IOService, ctx);
//
// The thread we are on now, is most likely the user interface thread.  Create a thread to handle all incoming socket work messages.
if (!RcvThreadCreated)
{
   WorkerThreads.create_thread(boost::bind(&SSLSocket::RcvWorkerThread, this));
   RcvThreadCreated = true;
   WorkerThreads.create_thread(boost::bind(&SSLSocket::SendWorkerThread, this));
 }
 // Try to connect to the server.  Note - add timeout logic at some point.
 boost::asio::async_connect(pSocket->lowest_layer(), EndpointIterator,
    boost::bind(&SSLSocket::HandleConnect, this, boost::asio::placeholders::error));
//创建解析器和查询对象,以将serverPath中的主机名解析为ip地址。
boost::asio::ip::tcp::解析器解析器(*IOService);
boost::asio::ip::tcp::resolver::query查询(服务器路径,端口);
boost::asio::ip::tcp::resolver::iterator EndpointIterator=resolver.resolve(查询);
//设置SSL上下文。
boost::asio::ssl::context ctx(*IOService,boost::asio::ssl::context::tlsv1_client);
//指定立即不验证服务器证书。
设置验证模式(boost::asio::ssl::context::verify\u none);
//Init最初用于与服务器通信的套接字对象。
pSocket=newboost::asio::ssl::stream(*IOService,ctx);
//
//我们现在使用的线程很可能是用户界面线程。创建一个线程来处理所有传入的套接字工作消息。
如果(!RcvThreadCreated)
{
创建线程(boost::bind(&SSLSocket::RcvWorkerThread,this));
RcvThreadCreated=true;
创建线程(boost::bind(&SSLSocket::SendWorkerThread,this));
}
//尝试连接到服务器。注意-在某个点添加超时逻辑。
boost::asio::async_connect(pSocket->lower_layer(),EndpointIterator,
boost::bind(&SSLSocket::HandleConnect,this,boost::asio::placeholder::error));

工作线程处理所有套接字I/O。这取决于您正在执行的操作,但是需要从另一个线程创建用于维护套接字的2个工作线程。如果需要,另一个线程可以是用户界面线程或主线程,因为它将很快返回。如果您与服务器或客户端有多个连接,则由您决定是否需要多组线程为其提供服务。

谢谢您的回复。。我正在使用的这个设备还可以连接到多个客户端,所以当在其中进行更新时,它会广播状态更新,所以我想,我需要一个线程来监听它。。但是套接字的创建和编写呢……在这种情况下,您需要提供更多关于您正试图做什么的信息。例如,在服务器应用程序中,您通常要为每个客户机创建一个线程,然后该线程处理与该客户机的连接,并在客户机断开连接后终止。如果您有多个客户端只等待状态更新,您可以使用一个线程来完成此操作:为客户端保留一个包含套接字的列表,每次您要向每个客户端发送内容时,您都要遍历该列表并将消息一个接一个地发送给一个客户端。谢谢@Bob Bryan。我想我从您的帖子中得到了解决方案:)