IBR-DTNSuite 0.6

ibrcommon/ibrcommon/net/tcpserver.cpp

Go to the documentation of this file.
00001 /*
00002  * tcpserver.cpp
00003  *
00004  *  Created on: 30.07.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/net/tcpserver.h"
00010 #include "ibrcommon/thread/MutexLock.h"
00011 #include <sys/socket.h>
00012 #include <fcntl.h>
00013 
00014 namespace ibrcommon
00015 {
00016         tcpserver::tcpserver()
00017          : _socket()
00018         {
00019         }
00020 
00021         tcpserver::tcpserver(const ibrcommon::File &s)
00022          : _socket()
00023         {
00024                 _socket.bind(s);
00025 
00026                 // listen on the socket, max. 5 concurrent awaiting connections
00027                 listen(5);
00028         }
00029 
00030         void tcpserver::listen(int connections)
00031         {
00032                 _socket.listen(connections);
00033         }
00034 
00035         void tcpserver::bind(int port, bool reuseaddr)
00036         {
00037                 // enable reuse address if requested
00038                 if (reuseaddr)
00039                 {
00040                         _socket.set(vsocket::VSOCKET_REUSEADDR);
00041                 }
00042 
00043                 // bind to the socket
00044                 _socket.bind(port);
00045                 _socket.listen(5);
00046 
00047                 // set linger socket option
00048                 _socket.set(vsocket::VSOCKET_LINGER);
00049 
00050                 // set socket to nonblocking
00051                 _socket.set(vsocket::VSOCKET_NONBLOCKING);
00052         }
00053 
00054         void tcpserver::bind(const vinterface &net, int port, bool reuseaddr)
00055         {
00056                 // enable reuse address if requested
00057                 if (reuseaddr)
00058                 {
00059                         _socket.set(vsocket::VSOCKET_REUSEADDR);
00060                 }
00061 
00062                 // bind to the socket
00063                 _socket.bind(net, port);
00064 
00065 
00066                 _socket.listen(5);
00067 
00068                 // set linger socket option
00069                 _socket.set(vsocket::VSOCKET_LINGER);
00070 
00071                 // set socket to nonblocking
00072                 _socket.set(vsocket::VSOCKET_NONBLOCKING);
00073         }
00074 
00075         tcpserver::~tcpserver()
00076         {
00077                 close();
00078         }
00079 
00080         void tcpserver::close()
00081         {
00082                 _socket.close();
00083         }
00084 
00085         void tcpserver::shutdown()
00086         {
00087                 _socket.shutdown();
00088         }
00089 
00090         tcpstream* tcpserver::accept()
00091         {
00092                 std::list<int> fds;
00093 
00094                 while (true)
00095                 {
00096                         _socket.select(fds, NULL);
00097 
00098                         for (std::list<int>::const_iterator iter = fds.begin(); iter != fds.end(); iter++)
00099                         {
00100                                 int fd = *iter;
00101 
00102                                 struct sockaddr_in cliaddr;
00103                                 socklen_t len;
00104                                 len = sizeof(cliaddr);
00105 
00106                                 int new_fd = ::accept(fd, (struct sockaddr *) &cliaddr, &len );
00107 
00108                                 if (new_fd <= 0)
00109                                 {
00110                                         throw vsocket_exception("accept failed");
00111                                 }
00112 
00113                                 return new tcpstream(new_fd);
00114                         }
00115                 }
00116 
00117                 throw vsocket_exception("tcpserver down");
00118         }
00119 }