00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/net/udpsocket.h"
00009 #include <sys/socket.h>
00010 #include <errno.h>
00011 #include <sys/types.h>
00012 #include <netinet/in.h>
00013 #include <arpa/inet.h>
00014 #include <cassert>
00015 #include <string.h>
00016
00017 namespace ibrcommon
00018 {
00019 udpsocket::udpsocket(u_char proto) throw (SocketException)
00020 {
00021
00022 if ((_socket = ::socket(AF_INET, SOCK_DGRAM, proto)) < 0)
00023 {
00024 throw SocketException("udpsocket: cannot create listen socket");
00025 }
00026
00027 bzero(&_sockaddr, sizeof(_sockaddr));
00028 _sockaddr.sin_family = AF_INET;
00029 }
00030
00031 udpsocket::~udpsocket()
00032 {
00033 if (_socket != 0)
00034 {
00035 shutdown();
00036 ::close(_socket);
00037 }
00038 }
00039
00040 void udpsocket::shutdown()
00041 {
00042 ::shutdown(_socket, SHUT_RDWR);
00043 }
00044
00045 int udpsocket::receive(char* data, size_t maxbuffer)
00046 {
00047 struct sockaddr_in clientAddress;
00048 socklen_t clientAddressLength = sizeof(clientAddress);
00049
00050
00051 return recvfrom(_socket, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength);
00052 }
00053
00054 udpsocket::peer::peer(udpsocket &socket, const struct sockaddr_in &dest, const unsigned int port)
00055 : _socket(socket)
00056 {
00057
00058 _destaddress.sin_family = AF_INET;
00059
00060
00061 memcpy(&_destaddress.sin_addr, &dest.sin_addr, sizeof(_destaddress.sin_addr));
00062 _destaddress.sin_port = htons(port);
00063 }
00064
00065 int udpsocket::peer::send(const char *data, const size_t length)
00066 {
00067
00068 return ::sendto(_socket._socket, data, length, 0, (struct sockaddr *) &_destaddress, sizeof(_destaddress));
00069 }
00070
00071 udpsocket::peer udpsocket::getPeer(const string address, const unsigned int port)
00072 {
00073 struct sockaddr_in destaddress;
00074
00075
00076 if (inet_pton(AF_INET, address.c_str(), &destaddress.sin_addr) <= 0)
00077 {
00078 throw SocketException("udpsocket: can not parse address " + address);
00079 }
00080
00081 return udpsocket::peer(*this, destaddress, port);
00082 }
00083 }