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