|
IBR-DTNSuite 0.6
|
00001 /* 00002 * udpsocket.cpp 00003 * 00004 * Created on: 02.03.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrcommon/config.h" 00009 #include "ibrcommon/net/udpsocket.h" 00010 #include "ibrcommon/Logger.h" 00011 #include <sys/socket.h> 00012 #include <errno.h> 00013 #include <sys/types.h> 00014 #include <netinet/in.h> 00015 #include <arpa/inet.h> 00016 #include <string.h> 00017 00018 #ifndef HAVE_BZERO 00019 #define bzero(s,n) (memset((s), '\0', (n)), (void) 0) 00020 #endif 00021 00022 namespace ibrcommon 00023 { 00024 udpsocket::udpsocket() throw (SocketException) 00025 { 00026 } 00027 00028 udpsocket::~udpsocket() 00029 { 00030 _socket.close(); 00031 } 00032 00033 void udpsocket::shutdown() 00034 { 00035 _socket.close(); 00036 } 00037 00038 int udpsocket::receive(char* data, size_t maxbuffer) 00039 { 00040 struct sockaddr_in clientAddress; 00041 socklen_t clientAddressLength = sizeof(clientAddress); 00042 00043 std::list<int> fds; 00044 _socket.select(fds, NULL); 00045 int fd = fds.front(); 00046 00047 // data waiting 00048 return recvfrom(fd, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength); 00049 } 00050 00051 int udpsocket::receive(char* data, size_t maxbuffer, std::string &address) 00052 { 00053 struct sockaddr_in clientAddress; 00054 socklen_t clientAddressLength = sizeof(clientAddress); 00055 00056 std::list<int> fds; 00057 _socket.select(fds, NULL); 00058 int fd = fds.front(); 00059 00060 // data waiting 00061 int ret = recvfrom(fd, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength); 00062 00063 char str[INET_ADDRSTRLEN]; 00064 inet_ntop(AF_INET, &(clientAddress.sin_addr), str, INET_ADDRSTRLEN); 00065 00066 address = std::string(str); 00067 00068 return ret; 00069 } 00070 00071 int udpsocket::send(const ibrcommon::vaddress &addr, const unsigned int port, const char *data, const size_t length) 00072 { 00073 int stat = -1; 00074 00075 // iterate over all sockets 00076 std::list<int> fds = _socket.get(); 00077 00078 for (std::list<int>::const_iterator iter = fds.begin(); iter != fds.end(); iter++) 00079 { 00080 try { 00081 size_t ret = 0; 00082 int flags = 0; 00083 00084 struct addrinfo hints, *ainfo; 00085 memset(&hints, 0, sizeof hints); 00086 00087 hints.ai_socktype = SOCK_DGRAM; 00088 ainfo = addr.addrinfo(&hints, port); 00089 00090 ret = ::sendto(*iter, data, length, flags, ainfo->ai_addr, ainfo->ai_addrlen); 00091 00092 // if the send was successful, set the correct return value 00093 if (ret != -1) stat = ret; 00094 00095 freeaddrinfo(ainfo); 00096 } catch (const ibrcommon::vsocket_exception&) { 00097 IBRCOMMON_LOGGER_DEBUG(5) << "can not send message to " << addr.toString() << IBRCOMMON_LOGGER_ENDL; 00098 } 00099 } 00100 00101 return stat; 00102 } 00103 }