Go to the documentation of this file.00001
00002
00003
00004
00005
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 ibrcommon::select(_socket, fds, NULL);
00045 int fd = fds.front();
00046
00047
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 ibrcommon::select(_socket, fds, NULL);
00058 int fd = fds.front();
00059
00060
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
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
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 }