0

我希望实现一个全双工 tcp 流。这是一个例子。

//server.cpp

#include <SDKDDKVer.h>
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
#include <boost/thread.hpp>

boost::asio::ip::tcp::iostream SocketStream;

void ThreadA()
{
    for(;;)
    {
        std::string Line;
        std::getline(SocketStream, Line);    //Y
        std::cout << Line << std::endl;
    }
}

void ThreadB()
{
    for(;;)
    {
        std::string Line;
        std::getline(std::cin, Line);     //Z
        SocketStream<<Line<<std::endl;    //X
    }
}

int main()
{  
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 4444);
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint);
    boost::system::error_code ec;
    acceptor.accept(*SocketStream.rdbuf(), ec);

    boost::thread tA(ThreadA);
    boost::thread tB(ThreadB);
    tA.join(); 
    tB.join();
    return 0;
}

//client.cpp

#include <SDKDDKVer.h>
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
#include <boost/thread.hpp>


boost::asio::ip::tcp::iostream SocketStream;

void ThreadA()
{
    for(;;)
    {
        std::string Line;
        std::getline(SocketStream, Line);    
        std::cout << Line << std::endl;
    }
}

void ThreadB()
{
    for(;;)
    {
        std::string Line;
        std::getline(std::cin, Line);     
        SocketStream<<Line<<std::endl;    
    }
}

int main()
{  
    boost::system::error_code ec;
    SocketStream.connect("127.0.0.1", "4444");

    boost::thread tA(ThreadA);
    //boost::thread tB(ThreadB);
    tA.join(); 
    //tB.join();
    return 0;
}

但它会在 X 行阻塞。
Q1,我做错了什么还是boost::asio::ip::tcp::iostream根本无法做到这一点?
Q2,如果boost::asio::ip::tcp::iostream不能完成任务,我还应该用什么?
我看到boost::iostream有一个双向模式。这就是我要找的吗?我不熟悉,boost::iostream所以我不确定它的真正作用。
如果boost::iostream也失败了,那么我必须使用boost::asio's 异步操作吗?因为我想要的是让套接字真正表现得像一个流,并且包装异步操作可能很困难。

附加:我希望SocketStream在读取时也可以写入,这意味着流是全双工的。

请,任何建议将不胜感激!

4

1 回答 1

1

类的实例boost::asio不是线程安全的(io_service 只是个例外)。所以你不能boost::asio::ip::tcp::iostream在 2 个线程中使用单个实例。

为了完成这个任务,我更喜欢使用异步操作和额外的线程来读取标准输入,因为这个读取是阻塞的。因此,从 stdin 和asio::write到对等点执行getline的线程之一。接收到使用async_read_until读取直到的其他线程。此外,您的服务器似乎不能与多个对等方一起工作,因此您将能够使用async_accept处理此问题\r\n

于 2013-07-06T06:01:04.237 回答