245 lines
6.3 KiB
C++
245 lines
6.3 KiB
C++
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
|
|
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <dlib/sockets.h>
|
|
#include <dlib/server.h>
|
|
#include <dlib/misc_api.h>
|
|
|
|
#include "tester.h"
|
|
|
|
namespace {
|
|
|
|
using namespace test;
|
|
using namespace dlib;
|
|
using namespace std;
|
|
|
|
dlib::mutex gm;
|
|
dlib::signaler gs(gm);
|
|
const char magic_num = 42;
|
|
const int min_bytes_sent = 10000;
|
|
int assigned_port;
|
|
|
|
logger dlog("test.sockets");
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
class serv : public server::kernel_1a_c
|
|
{
|
|
public:
|
|
serv (
|
|
) :
|
|
error_occurred (false),
|
|
got_connections(false)
|
|
{}
|
|
|
|
void on_listening_port_assigned (
|
|
)
|
|
{
|
|
auto_mutex M(gm);
|
|
assigned_port = get_listening_port();
|
|
gs.broadcast();
|
|
}
|
|
|
|
|
|
void on_connect (
|
|
connection& con
|
|
)
|
|
{
|
|
dlog << LINFO << "in serv::on_connect(): got new connection";
|
|
int status;
|
|
int count = 0;
|
|
char buf[100];
|
|
while ((status = con.read(buf,sizeof(buf))) > 0)
|
|
{
|
|
for (int i = 0; i < status; ++i)
|
|
{
|
|
if (buf[i] != magic_num)
|
|
{
|
|
tag = 4.0;
|
|
error_occurred = true;
|
|
}
|
|
}
|
|
count += status;
|
|
}
|
|
if (count != min_bytes_sent)
|
|
{
|
|
tag = 5.0;
|
|
error_occurred = true;
|
|
}
|
|
got_connections = true;
|
|
dlog << LINFO << "in serv::on_connect(): on_connect ending";
|
|
}
|
|
|
|
bool error_occurred;
|
|
bool got_connections;
|
|
double tag;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
class thread_container : public multithreaded_object
|
|
{
|
|
public:
|
|
|
|
serv& srv;
|
|
|
|
thread_container (
|
|
serv& srv_
|
|
) : srv(srv_)
|
|
{
|
|
for (int i = 0; i < 10; ++i)
|
|
register_thread(*this, &thread_container::thread_proc);
|
|
|
|
// start up the threads
|
|
start();
|
|
}
|
|
|
|
~thread_container ()
|
|
{
|
|
// wait for all threads to terminate
|
|
wait();
|
|
}
|
|
|
|
void thread_proc (
|
|
)
|
|
{
|
|
try
|
|
{
|
|
dlog << LTRACE << "enter thread";
|
|
{
|
|
auto_mutex M(gm);
|
|
while (assigned_port == 0)
|
|
gs.wait();
|
|
}
|
|
|
|
int status;
|
|
scoped_ptr<connection> con;
|
|
string hostname;
|
|
string ip;
|
|
status = get_local_hostname(hostname);
|
|
if (status)
|
|
{
|
|
srv.tag = 1.0;
|
|
srv.error_occurred = true;
|
|
srv.clear();
|
|
dlog << LERROR << "leaving thread, line: " << __LINE__;
|
|
dlog << LERROR << "get_local_hostname() failed";
|
|
return;
|
|
}
|
|
|
|
status = hostname_to_ip(hostname,ip);
|
|
if (status)
|
|
{
|
|
srv.tag = 2.0;
|
|
srv.error_occurred = true;
|
|
srv.clear();
|
|
dlog << LERROR << "leaving thread, line: " << __LINE__;
|
|
dlog << LERROR << "hostname_to_ip() failed";
|
|
return;
|
|
}
|
|
|
|
dlog << LTRACE << "try to connect to the server at port " << srv.get_listening_port();
|
|
status = create_connection(con,srv.get_listening_port(),ip);
|
|
if (status)
|
|
{
|
|
srv.tag = 3.0;
|
|
srv.error_occurred = true;
|
|
srv.clear();
|
|
dlog << LERROR << "leaving thread, line: " << __LINE__;
|
|
dlog << LERROR << "create_connection() failed";
|
|
return;
|
|
}
|
|
|
|
dlog << LTRACE << "sending magic_num to server";
|
|
int i;
|
|
for (i = 0; i < min_bytes_sent; ++i)
|
|
{
|
|
con->write(&magic_num,1);
|
|
}
|
|
|
|
dlog << LTRACE << "shutting down connection to server";
|
|
close_gracefully(con);
|
|
dlog << LTRACE << "finished calling close_gracefully() on the connection";
|
|
}
|
|
catch (exception& e)
|
|
{
|
|
srv.error_occurred = true;
|
|
dlog << LERROR << "exception thrown in thread_proc(): " << e.what();
|
|
cout << "exception thrown in thread_proc(): " << e.what();
|
|
}
|
|
dlog << LTRACE << "exit thread";
|
|
}
|
|
};
|
|
|
|
void run_server(serv* srv)
|
|
{
|
|
dlog << LTRACE << "calling srv.start()";
|
|
srv->start();
|
|
dlog << LTRACE << "srv.start() just ended.";
|
|
}
|
|
|
|
void sockets_test (
|
|
)
|
|
/*!
|
|
requires
|
|
- sockets is an implementation of sockets/sockets_kernel_abstract.h
|
|
is instantiated with int
|
|
ensures
|
|
- runs tests on sockets for compliance with the specs
|
|
!*/
|
|
{
|
|
|
|
dlog << LTRACE << "starting test";
|
|
serv srv;
|
|
|
|
assigned_port = 0;
|
|
|
|
|
|
dlog << LTRACE << "spawning threads";
|
|
thread_container stuff(srv);
|
|
|
|
|
|
|
|
thread_function thread2(run_server, &srv);
|
|
|
|
// wait until all the sending threads have ended
|
|
stuff.wait();
|
|
|
|
if (srv.error_occurred)
|
|
{
|
|
dlog << LDEBUG << "tag: " << srv.tag;
|
|
}
|
|
|
|
srv.clear();
|
|
|
|
dlog << LTRACE << "ending successful test";
|
|
DLIB_TEST( !srv.error_occurred);
|
|
DLIB_TEST( srv.got_connections);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
class sockets_tester : public tester
|
|
{
|
|
public:
|
|
sockets_tester (
|
|
) :
|
|
tester ("test_sockets",
|
|
"Runs tests on the sockets component.")
|
|
{}
|
|
|
|
void perform_test (
|
|
)
|
|
{
|
|
sockets_test();
|
|
}
|
|
} a;
|
|
|
|
}
|
|
|