Tcp ลูกค้าไม่ได้โยเกิดข้อผิดพลาดขึ้นระหว่างเชื่อมต่อกับ localhost ถ้าไม่เซิร์ฟเวอร์พร้อม

0

คำถาม

ฉันพยายามจะ encapsulate ทั้งระบบเครือข่าย functionalities สำหรับโปรแกรมของผมใน"SimpleClient"ชั้นเรียนที่เปิดโปงนี้ส่วนติดต่อภายใน.hpp แฟ้ม:

class SimpleClient{
    //private
        boost::shared_ptr<boost::asio::ip::tcp::socket> signal_socket; 
    protected: 
        boost::asio::io_context my_context;
        ClientState state; //0: Ready to be used, not connected,  -1: error, 1: Connected/active, 
    public: 
       SimpleClient();
       virtual bool connect(const char* ip_address);
       virtual void disconnect();
       virtual bool sendMessage(const char* msg, int length);
       virtual int getResponse( char* msg, int length, int timeout);
       virtual int getSignalData( char* msg, int length);
       virtual ClientState getState();
};

ในขณะที่ทดสอบเชื่อมต่อวิธีการฉันสังเกตเห็นว่าถึงแม้ไม่มีเซิร์ฟเวอร์กำลังรอ localhost บพอร์ต 8887 ที่เชื่อมต่อไม่ได้ทิ้งข้อผิดพลาด จะให้ฉันตรวจสอบว่าที่ซ็อกเกตได้คือเชื่อมต่อสำหรับของจริงเหรอ?

ที่นี่วิธีการของฉัการจัดเตรียมไว้แล้วเล็กๆตัวอย่างเช่นนั้น reproduces ของฉันพฤติกรรมใช้กำลังใจ.ทดสอบ:

SimpleClient::SimpleClient() : my_context() {
    signal_socket.reset();
    state = ClientState::CL_UNCON;
}

bool SimpleClient::connect(const char* ip_address) {
    boost::system::error_code ec;
    if (signal_socket != NULL && signal_socket->is_open() )
        return true;
    try {
        boost::asio::ip::tcp::endpoint signal_endpoint(boost::asio::ip::make_address(ip_address), 8887);
        signal_socket.reset(new boost::asio::ip::tcp::socket(my_context));
        signal_socket->connect(signal_endpoint, ec);
        if(ec) {
            std::cout<<ec.message()<<" "<<ec.value()<<std::endl;
            return false;
        }
    } catch(const boost::system::system_error& ex) {
        std::cout<<ex.code()<<std::endl;
        return false;
    }
    std::cout<<signal_socket<<std::endl;
    state = ClientState::CL_READY;
    return true;
}

ที่นี่คือการทดสอบโปรแกรม:

#define BOOST_AUTO_TEST_MAIN 
#define BOOST_TEST_DYN_LINK

#include "SimpleClient.hpp"

#include <boost/test/unit_test.hpp>

#include <string.h>

#define TARGET_IP "127.0.0.1"
#define BAD_IP "128.0.0.1"


BOOST_AUTO_TEST_CASE(connection_test)  {
    bool ret;
    std::cout<<"Connect to WRONG address"<<std::endl;
    SimpleClient* ut = new SimpleClient();
    BOOST_CHECK_EQUAL(ut->getState(), ClientState::CL_UNCON);
    ret = ut->connect(BAD_IP);
    BOOST_CHECK(!ret);
    std::cout<<"Connect to RIGHT address"<<std::endl;
    ret = ut->connect(TARGET_IP);
    BOOST_CHECK(ret);
    ut->disconnect();
    try{
        delete ut;
    }
    catch(const std::exception& ex) {
        std::cout<<ex.what()<<std::endl;
    }
    catch(...) {
    }
} 
boost boost-asio c++ tcp
2021-11-22 09:30:07
1

คำตอบที่ดีที่สุด

1

ปัญหาคือในสมองของฉัเชื่อมต่อวิธีการแน่นอน คนแรกโทรหาเพื่อนที่เชื่อมโยงข้างในของฉันล้มเหลวในการทดสอบ,แต่มันไม่ได้ปิดจากซ็อกเกต,ดังนั้นที่สองเรียกโดยอัตโนมัติกลับมาเรื่องจริงโดยไม่แสดงมีปฏิบัติการนี้

TLDR:ในกรณีของความล้มเหลวต่อสามีไม่ได้ปิดซ็อกเก็ตและมีโทรหาเพื่อ is_open()จะคืน'จริง'โทรหาด้วยตนเองใกล้ชิด()วิธีการที่ซ็อกเก็ตในกรณีของผิดพลาด

bool SimpleClient::connect(const char* ip_address) {
    boost::system::error_code ec;
    if (signal_socket != NULL && signal_socket->is_open() )
        return true;
    try {
        boost::asio::ip::tcp::endpoint signal_endpoint(boost::asio::ip::make_address(ip_address), 8887);
        signal_socket.reset(new boost::asio::ip::tcp::socket(my_context));
        signal_socket->connect(signal_endpoint, ec);
        if(ec) {
            std::cout<<ec.message()<<" "<<ec.value()<<std::endl;
            signal_socket->close();
            signal_socket.reset();
            return false;
        }
    } catch(const boost::system::system_error& ex) {
        std::cout<<ex.code()<<std::endl;
        signal_socket->close();
        signal_socket.reset();
        return false;
    }
    std::cout<<signal_socket<<std::endl;
    state = ClientState::CL_READY;
    return true;
}
2021-11-22 14:52:56

อีกทางเลือกปรับค่าควบคุมเลื่อนไหลดังนั้นคนจากซ็อกเกตไม่เคยหลังจากมีข้อผิดพลาด นี่คือมากกว่าธรรมชาติใกล้เข้ามาแล้ว บ่อยตรวจ"is_open"ไม่ใช่สิ่งที่คุณกำลังตามล่ายังไงก็ตาม(e.g. มันจะไม่สามารถระบุสิ่งที่ผิดปกติทางไกลเมื่อตอนที่สิ้นสุดถูกปิดการเชื่อมต่อ). +1 สำหรับตอบกลับของตัวเองคำถามนะ
sehe

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่