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