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 <sys/socket.h>
00011 #include <errno.h>
00012 #include <sys/types.h>
00013 #include <netinet/in.h>
00014 #include <arpa/inet.h>
00015 #include <cassert>
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(u_char proto) throw (SocketException)
00025 {
00026
00027 if ((_socket = ::socket(AF_INET, SOCK_DGRAM, proto)) < 0)
00028 {
00029 throw SocketException("udpsocket: cannot create listen socket");
00030 }
00031
00032 bzero(&_sockaddr, sizeof(_sockaddr));
00033 _sockaddr.sin_family = AF_INET;
00034 }
00035
00036 udpsocket::~udpsocket()
00037 {
00038 if (_socket != 0)
00039 {
00040 shutdown();
00041 ::close(_socket);
00042 }
00043 }
00044
00045 void udpsocket::shutdown()
00046 {
00047
00048 ::close(_socket);
00049 }
00050
00051 int udpsocket::receive(char* data, size_t maxbuffer)
00052 {
00053 struct sockaddr_in clientAddress;
00054 socklen_t clientAddressLength = sizeof(clientAddress);
00055
00056
00057 return recvfrom(_socket, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength);
00058 }
00059
00060 int udpsocket::receive(char* data, size_t maxbuffer, std::string &address)
00061 {
00062 struct sockaddr_in clientAddress;
00063 socklen_t clientAddressLength = sizeof(clientAddress);
00064
00065
00066 int ret = recvfrom(_socket, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength);
00067
00068 char str[INET_ADDRSTRLEN];
00069 inet_ntop(AF_INET, &(clientAddress.sin_addr), str, INET_ADDRSTRLEN);
00070
00071 address = std::string(str);
00072
00073 return ret;
00074 }
00075
00076 udpsocket::peer::peer(udpsocket &socket, const struct sockaddr_in &dest, const unsigned int port)
00077 : _socket(socket)
00078 {
00079
00080 _destaddress.sin_family = AF_INET;
00081
00082
00083 memcpy(&_destaddress.sin_addr, &dest.sin_addr, sizeof(_destaddress.sin_addr));
00084 _destaddress.sin_port = htons(port);
00085 }
00086
00087 int udpsocket::peer::send(const char *data, const size_t length)
00088 {
00089
00090 return ::sendto(_socket._socket, data, length, 0, (struct sockaddr *) &_destaddress, sizeof(_destaddress));
00091 }
00092
00093 udpsocket::peer udpsocket::getPeer(const string address, const unsigned int port)
00094 {
00095 struct sockaddr_in destaddress;
00096
00097
00098 if (inet_pton(AF_INET, address.c_str(), &destaddress.sin_addr) <= 0)
00099 {
00100 throw SocketException("udpsocket: can not parse address " + address);
00101 }
00102
00103 return udpsocket::peer(*this, destaddress, port);
00104 }
00105 }