libt2n: (gerd) add ip communication
authorGerd v. Egidy <gerd.von.egidy@intra2net.com>
Thu, 12 Oct 2006 09:35:41 +0000 (09:35 +0000)
committerGerd v. Egidy <gerd.von.egidy@intra2net.com>
Thu, 12 Oct 2006 09:35:41 +0000 (09:35 +0000)
src/socket_client.hxx
src/socket_server.cpp
src/socket_server.hxx
src/t2n_exception.hxx
test/comm.cpp

index 8a379f8..d680813 100644 (file)
@@ -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)
index 87025d8..b807fdd 100644 (file)
@@ -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())
index a72ae48..e3a4f34 100644 (file)
@@ -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();
index 7b68c21..9d789b5 100644 (file)
@@ -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
index 60907b2..55c5632 100644 (file)
@@ -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);