简体   繁体   English

boost::asio::write() VS socket->write_some()

[英]boost::asio::write() VS socket->write_some()

I am trying to learn boost::asi o and I have some problems with boost::asio::write() , socket->write_some() .我正在尝试学习boost::asi o,我在使用boost::asio::write()socket->write_some()时遇到了一些问题。 From what I read until now I learn that boost::asio::write assure that all data was transfer while socket->write doesn't do that because is using send from OS and this doesn't guarantee full transmission.从我读到现在我了解到boost::asio::write确保所有数据都已传输,而socket->write不这样做,因为正在使用从操作系统send ,这不能保证完全传输。

Here is a part of my client/server app.这是我的client/server应用程序的一部分。

server服务器

void server::session(socket_ptr sock)
{
char data[MAX_SIZE] = {};
bool flag = false;
sprintf(data,"On the server are %d users.",user_vector.size());

//boost::asio::write(*sock, boost::asio::buffer(data, strlen(data)));
sock->write_some(boost::asio::buffer(data, strlen(data)));

cleanMemory(data,strlen(data));
try
{
    for (;;)
    {
        boost::system::error_code error;
        size_t length = sock->read_some(boost::asio::buffer(data), error);
        //boost::asio::write(*sock, boost::asio::buffer(data,strlen(data)));
        cout << std::endl << data;
        cleanMemory(data, strlen(data));
        if (error == boost::asio::error::eof)
        {
            std::vector<user_detail>::iterator it = user_vector.begin();
            for (; it!= user_vector.end();)
            {
                std::pair<socket_ptr, int> user = *it;
                if (user.first == sock)
                {
                    cout << "User " << user.second << " leave server." << std::endl;
                    cout << std::endl << "Connection has been closed." << std::endl;
                    it = user_vector.erase(it);
                    flag = true;
                    break;
                }
                else
                    ++it;
            }
            if (flag)
                break;
        }
    }
}
catch (const std::exception&e) {
    std::cerr << "Error in threead : " << e.what() << endl;
}
}

client客户

size_t length = s.read_some(boost::asio::buffer(buf,100)); //OK DATA RECEVIED
    //boost::asio::read(s, boost::asio::buffer(buf, 100));//FAIL TO RECEIVE DATA
    cout.write(buf,strlen(buf));

The problem is on the client side.问题出在客户端。 If I use:如果我使用:

size_t length = s.read_some(boost::asio::buffer(buf,100));

Works ok and data is recevide but if i use:工作正常,数据已接收,但如果我使用:

boost::asio::read(s, boost::asio::buffer(buf, 100));

Data is lost.数据丢失。

Question:问题:

  1. If the server sends data, for example using boost::asio::write client need to use boost::asio::read or can also use socket.read_some() ?如果服务器发送数据,例如使用boost::asio::write客户端需要使用boost::asio::read或者也可以使用socket.read_some()
  2. What is more exactly connection between boost::Asio::read and socket->read_some , and why does this work only if i use s.read_some(boost::asio::buffer(buf,100)); boost::Asio::readsocket->read_some之间更确切的联系是什么,为什么只有当我使用s.read_some(boost::asio::buffer(buf,100));时才有效? ?

boost::asio::read() will read until boost::asio::read()将读取直到

a) all 100 bytes has been read, or a) 所有 100 个字节都已读取,或者

b) there is an error, or b) 有错误,或

c) there is an end-of-stream condition. c) 存在流结束条件。

It is a compound operation.这是一个复合操作。 One of the effects of that is that it can both return an error and have read some data.其影响之一是它既可以返回错误又可以读取一些数据。

For example, if 50 bytes are read and then the stream enters an eof condition, the bytes_transferred will be 50 and the error_code returned will indicate end of file.例如,如果读取了 50 个字节,然后 stream 进入 eof 条件,则bytes_transferred将为 50,返回的 error_code 将指示文件结束。

With a compound operation it's important to check the bytes_transferred before you check the error.对于复合操作,在检查错误之前检查 bytes_transferred 很重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM