首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >*asio:数据损坏

*asio:数据损坏
EN

Stack Overflow用户
提问于 2014-04-15 04:37:20
回答 1查看 867关注 0票数 3

我介绍了一个用Asio编写的简单客户端和服务器,以显示可能是错误的东西。客户端反复向服务器和服务器发送长度为102的固定字符串,并检查字符串是否正确,如果不正确,则写入错误消息并退出。

代码在debian 7 (amd64)中编译和运行。

我的处理器有两个核

boost版本为1.55

在运行服务器和客户端时,在发送几千个数据包后,会收到错误的数据包。(可能需要重复测试几次)。

有什么问题吗?

Makefile

代码语言:javascript
复制
CXX=g++
LIBS = -lboost_thread -lboost_filesystem -lboost_system

all: server asyncclient
server: server.o
    $(CXX) $(LIBS) server.o -o server
asyncclient: asyncclient.o
    $(CXX) $(LIBS) asyncclient.o -o asyncclient
server.o: server.cpp
    $(CXX) -c server.cpp
asyncclient.o: asyncclient.cpp
    $(CXX) -c asyncclient.cpp

server.cpp

代码语言:javascript
复制
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
using boost::asio::ip::tcp;
char teststr[]="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n";
void session(tcp::socket* sock)
{
    boost::array<char, 102> buf;// 102 == sizeof(teststr)
    int i=0;
    try
    {
            for (;;)
            {
                    std::cout<<i++<<std::endl;
                    boost::system::error_code error;
                    size_t length = boost::asio::read(*sock, boost::asio::buffer(buf), error);
                    if (error == boost::asio::error::eof)
                            break; // Connection closed cleanly by peer.
                    else if (error)
                            throw boost::system::system_error(error); // Some other error.
                    if(strcmp(buf.data(), teststr)!=0)
                    {
                            std::cerr<<"error"<<std::endl;
                            std::cerr<<"    buf.data() = "<<
                                    std::string(buf.data(), buf.size())<<std::endl;
                            return;
                    }
            }
    }
    catch (std::exception& e)
    {
            std::cerr << "Exception: " << e.what() << "\n";
    }
}

int main()
{
    std::cerr<<"sizeof(teststr) = "<<sizeof(teststr)<<std::endl;//DEBUG
    boost::asio::io_service ios;
    tcp::acceptor a(ios, tcp::endpoint(tcp::v4(), 41000));
    tcp::socket sock(ios);
    a.accept(sock);
    boost::thread t(boost::bind(session, &sock));
    t.join();
}

asyncclient.cpp

代码语言:javascript
复制
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

using boost::asio::ip::tcp;

char teststr[]="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n";

void handle_write(size_t num_bytes, boost::system::error_code e)
{
    static int i=0;
    if(!e)
    {
        std::cout<<i++<<std::endl;
    }
    else
    {
        std::cout<<"Error: "<<e.message()<<std::endl;
        exit(1);
    }
}

int main()
{
    boost::asio::io_service ios;

    tcp::resolver r(ios);
    tcp::resolver::query q(tcp::v4(), "127.0.0.1", "41000");
    tcp::resolver::iterator it = r.resolve(q);

    tcp::socket sock(ios);
    boost::asio::connect(sock, it);

    boost::thread t(boost::bind(&boost::asio::io_service::run,&ios));
    try
    {
        for(;;)
        {
            boost::asio::async_write(sock, boost::asio::buffer(teststr,102),
                    boost::bind(&handle_write,
                    boost::asio::placeholders::bytes_transferred,
                    boost::asio::placeholders::error));
        }
    }
    catch(std::exception& e)
    {
        std::cout<<"Exception: "<<e.what()<<std::endl;
    }
    t.join();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-15 12:43:07

问题来自以下for循环:

代码语言:javascript
复制
for(;;)
    {
        boost::asio::async_write(sock, boost::asio::buffer(teststr,102),
                boost::bind(&handle_write,
                boost::asio::placeholders::bytes_transferred,
                boost::asio::placeholders::error));
    }

async_write操作可以在以前的async_write完成之前开始,这是不允许的。

参考文献:

正确的方法是消除for循环并在async_write函数中调用handle_write:

代码语言:javascript
复制
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

using boost::asio::ip::tcp;

char teststr[]="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n";

void handle_write(tcp::socket* sock, size_t num_bytes, boost::system::error_code e)
{
    static int i=0;
    if(!e)
    {
        std::cout<<i++<<std::endl;
        boost::asio::async_write(*sock, boost::asio::buffer(teststr,102),
                boost::bind(&handle_write, sock,
                    boost::asio::placeholders::bytes_transferred,
                    boost::asio::placeholders::error));
    }
    else
    {
        std::cout<<"Error: "<<e.message()<<std::endl;
        exit(1);
    }
}

int main()
{
    boost::asio::io_service ios;

    tcp::resolver r(ios);
    tcp::resolver::query q(tcp::v4(), "127.0.0.1", "41000");
    tcp::resolver::iterator it = r.resolve(q);

    tcp::socket sock(ios);
    boost::asio::connect(sock, it);

    boost::thread t(boost::bind(&boost::asio::io_service::run,&ios));
    boost::asio::async_write(sock, boost::asio::buffer(teststr,102),
            boost::bind(&handle_write, &sock,
                boost::asio::placeholders::bytes_transferred,
                boost::asio::placeholders::error));
    t.join();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23074776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档