dlib C++ Library - sockets2.cpp

// Copyright (C) 2008 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#include <algorithm>
#include <memory>
#include "tester.h"
#include <dlib/sockets.h>
#include <dlib/threads.h>
#include <dlib/array.h>
// This is called an unnamed-namespace and it has the effect of making everything 
// inside this file "private" so that everything you declare will have static linkage. 
// Thus we won't have any multiply defined symbol errors coming out of the linker when 
// we try to compile the test suite.
namespace 
{
 using namespace test;
 using namespace dlib;
 using namespace std;
 // Declare the logger we will use in this test. The name of the logger 
 // should start with "test."
 dlib::logger dlog("test.sockets2");
 class sockets2_tester : public tester, private multithreaded_object 
 {
 /*!
 WHAT THIS OBJECT REPRESENTS
 This object represents a unit test. When it is constructed
 it adds itself into the testing framework.
 !*/
 short port_num;
 string data_to_send;
 bool test_failed;
 void write_thread (
 )
 {
 try
 {
 std::unique_ptr<connection> con(connect("127.0.0.1", port_num));
 // Send a copy of the data down the connection so we can test our the read() function
 // that uses timeouts in the main thread.
 if (con->write(data_to_send.data(), data_to_send.size()) != (int)data_to_send.size())
 {
 test_failed = true;
 dlog << LERROR << "failed to send all the data down the connection";
 }
 close_gracefully(con,300000);
 }
 catch (exception& e)
 {
 test_failed = true;
 dlog << LERROR << e.what();
 }
 }
 void no_write_thread (
 )
 {
 try
 {
 std::unique_ptr<connection> con(connect("127.0.0.1", port_num));
 // just do nothing until the connection closes
 char ch;
 con->read(&ch, 1);
 dlog << LDEBUG << "silent connection finally closing";
 }
 catch (exception& e)
 {
 test_failed = true;
 dlog << LERROR << e.what();
 }
 }
 public:
 sockets2_tester (
 ) :
 tester (
 "test_sockets2", // the command line argument name for this test
 "Run sockets2 tests.", // the command line argument description
 0 // the number of command line arguments for this test
 )
 {
 register_thread(*this, &sockets2_tester::write_thread);
 register_thread(*this, &sockets2_tester::write_thread);
 register_thread(*this, &sockets2_tester::write_thread);
 register_thread(*this, &sockets2_tester::write_thread);
 register_thread(*this, &sockets2_tester::write_thread);
 register_thread(*this, &sockets2_tester::no_write_thread);
 }
 void perform_test (
 )
 {
 run_tests(0);
 run_tests(40);
 }
 void run_tests (
 unsigned long timeout_to_use
 )
 {
 // make sure there aren't any threads running
 wait();
 port_num = 5000;
 test_failed = false;
 print_spinner();
 data_to_send = "oi 2m3ormao2m fo2im3fo23mi o2mi3 foa2m3fao23ifm2o3fmia23oima23iom3giugbiua";
 // make the block of data much larger
 for (int i = 0; i < 11; ++i)
 data_to_send = data_to_send + data_to_send;
 dlog << LINFO << "data block size: " << data_to_send.size();
 std::unique_ptr<listener> list;
 DLIB_TEST(create_listener(list, port_num, "127.0.0.1") == 0);
 DLIB_TEST(bool(list));
 // kick off the sending threads
 start();
 dlib::array<std::unique_ptr<connection> > cons;
 std::vector<long> bytes_received(6,0);
 std::unique_ptr<connection> con_temp;
 
 // accept the 6 connections we should get
 for (int i = 0; i < 6; ++i)
 {
 DLIB_TEST(list->accept(con_temp) == 0);
 cons.push_back(con_temp);
 print_spinner();
 }
 int finished_cons = 0;
 // now receive all the bytes from the sending threads
 while (finished_cons < 5)
 {
 for (unsigned long i = 0; i < cons.size(); ++i)
 {
 if (cons[i])
 {
 const int buf_size = 3000;
 char buf[buf_size];
 int status = cons[i]->read(buf, buf_size, timeout_to_use);
 if (status > 0)
 {
 DLIB_TEST(equal(buf, buf+status, data_to_send.begin()+bytes_received[i]));
 bytes_received[i] += status;
 }
 else if (status == 0)
 {
 // the connection is closed to kill it
 cons[i].reset();
 ++finished_cons;
 }
 }
 }
 print_spinner();
 }
 for (unsigned long i = 0; i < bytes_received.size(); ++i)
 {
 DLIB_TEST(bytes_received[i] == (long)data_to_send.size() || cons[i]);
 }
 dlog << LINFO << "All data received correctly";
 cons.clear();
 print_spinner();
 DLIB_TEST(test_failed == false);
 // wait for all the sending threads to terminate
 wait();
 }
 };
 // Create an instance of this object. Doing this causes this test
 // to be automatically inserted into the testing framework whenever this cpp file
 // is linked into the project. Note that since we are inside an unnamed-namespace 
 // we won't get any linker errors about the symbol a being defined multiple times. 
 sockets2_tester a;
}

AltStyle によって変換されたページ (->オリジナル) /