From: Gerd v. Egidy Date: Thu, 12 Oct 2006 09:35:41 +0000 (+0000) Subject: libt2n: (gerd) add ip communication X-Git-Tag: v0.2~144 X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=commitdiff_plain;h=cc68aabb16ec32278df8b071c4c9efec7e9f0dce;hp=9424729586fdb0aabb671d2f1266bdb07e0bed38 libt2n: (gerd) add ip communication --- diff --git a/src/socket_client.hxx b/src/socket_client.hxx index 8a379f8..d680813 100644 --- a/src/socket_client.hxx +++ b/src/socket_client.hxx @@ -30,7 +30,8 @@ namespace libt2n */ class socket_client_connection : public client_connection, public socket_handler { - static const int max_retries_default=3; + public: + static const int max_retries_default=3; private: void real_write(const std::string& data) diff --git a/src/socket_server.cpp b/src/socket_server.cpp index 87025d8..b807fdd 100644 --- a/src/socket_server.cpp +++ b/src/socket_server.cpp @@ -50,7 +50,40 @@ namespace libt2n socket_server::socket_server(int port, const std::string& ip) : server(), socket_handler(0,tcp_s) { - // TODO + /* Create the socket. */ + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + string err="error opening socket: "; + err+=strerror(errno); + log(error, err); + throw t2n_server_error(err); + } + + set_socket_options(sock); + + /* Give the socket a name. */ + struct sockaddr_in sockaddr; + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(port); + + if (inet_aton(ip.c_str(),&sockaddr.sin_addr) == 0) + { + string err="failed listening on invalid ip "; + err+=ip; + log(error, err); + throw t2n_server_error(err); + } + + if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0) + { + string err="error binding socket: "; + err+=strerror(errno); + log(error, err); + throw t2n_server_error(err); + } + + start_listening(); } /** @brief create a new unix-socked-based server @@ -132,6 +165,20 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std } } + start_listening(); +} + +socket_server::~socket_server() +{ + socket_handler::close(); + + if (get_type()==unix_s) + unlink(unix_path.c_str()); +} + +/// start listening on a new server socket (called by the constructors) +void socket_server::start_listening() +{ if (listen (sock, 5) < 0) { string err="error listening to socket: "; @@ -145,14 +192,7 @@ socket_server::socket_server(const std::string& path, mode_t filemode, const std FD_SET (sock, &connection_set); } -socket_server::~socket_server() -{ - socket_handler::close(); - - if (get_type()==unix_s) - unlink(unix_path.c_str()); -} - +/// handle a new connection from a client void socket_server::new_connection() { struct sockaddr_un clientname; @@ -238,6 +278,7 @@ bool socket_server::fill_buffer(long long usec_timeout) return false; } +/// call fill_buffer() on all connections, called from fill_buffer() bool socket_server::fill_connection_buffers() { bool data_found; @@ -251,6 +292,7 @@ bool socket_server::fill_connection_buffers() return data_found; } +/// remove the socket of a connection after the connection has been closed void socket_server::remove_connection_socket(int sock) { FD_CLR(sock, &connection_set); @@ -266,6 +308,7 @@ void socket_server_connection::log(log_level_values level, const char* message) } } +/// close this connection. complete data waiting in the buffer can still be retrieved. void socket_server_connection::close() { if (!server_connection::is_closed()) diff --git a/src/socket_server.hxx b/src/socket_server.hxx index a72ae48..e3a4f34 100644 --- a/src/socket_server.hxx +++ b/src/socket_server.hxx @@ -46,6 +46,8 @@ class socket_server : public socket_handler, public server fd_set connection_set; std::string unix_path; + void start_listening(); + void new_connection(); bool fill_connection_buffers(); diff --git a/src/t2n_exception.hxx b/src/t2n_exception.hxx index 7b68c21..9d789b5 100644 --- a/src/t2n_exception.hxx +++ b/src/t2n_exception.hxx @@ -264,8 +264,7 @@ class t2n_serialization_error : public t2n_exception }; BOOST_CLASS_EXPORT(t2n_serialization_error) -/** - a runtime error within the remote function +/** @brief a runtime error within the remote function. derive your own custom exceptions from this one */ class t2n_runtime_error : public t2n_exception diff --git a/test/comm.cpp b/test/comm.cpp index 60907b2..55c5632 100644 --- a/test/comm.cpp +++ b/test/comm.cpp @@ -32,6 +32,7 @@ class test_comm : public TestFixture CPPUNIT_TEST(UnixCommToServer); CPPUNIT_TEST(UnixCommToServerAndBack); + CPPUNIT_TEST(IPCommToServer); CPPUNIT_TEST_SUITE_END(); @@ -154,6 +155,47 @@ class test_comm : public TestFixture } } + void IPCommToServer() + { + pid_t pid; + string data; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + // wait till server is up + sleep(1); + socket_client_connection sc("localhost",6666,socket_client_connection::max_retries_default); + sc.write("hello"); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + socket_server ss(6666); + + // max 10 sec + for (int i=0; i < 10; i++) + { + ss.fill_buffer(1000000); + + if(ss.get_packet(data)) + break; + } + } + } + CPPUNIT_ASSERT_EQUAL(string("hello"),data); + } + }; CPPUNIT_TEST_SUITE_REGISTRATION(test_comm);