IBR-DTNSuite
0.8
|
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 }