• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/UdpSocket.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #include <spl/Char.h>
00018 #include <spl/Environment.h>
00019 #include <spl/net/UdpSocket.h>
00020 
00021 UdpSocket::UdpSocket(const UdpSocket& sock)
00022 : m_sock(sock.m_sock), m_address(sock.m_address), m_port(sock.m_port)
00023 {
00024 }
00025 
00026 UdpSocket& UdpSocket::operator =(const UdpSocket& sock)
00027 {
00028         m_sock = sock.m_sock; 
00029         m_address = sock.m_address; 
00030         m_port = sock.m_port;
00031 
00032         return *this;
00033 }
00034 
00035 UdpSocket::UdpSocket( int port )
00036 : m_sock(new Socket(0, AF_INET, SOCK_DGRAM, IPPROTO_UDP)), m_address(), m_port(port)
00037 {
00038         memset(&m_recvFromAddr, 0, sizeof(m_recvFromAddr));
00039 
00040         SOCKADDR_IN local;
00041         local.sin_family = AF_INET;
00042         local.sin_addr.s_addr = 0;
00043         local.sin_port = port;
00044         
00045         if (0 != ::bind(m_sock->GetFD(), (sockaddr *)&local, sizeof(local)))
00046         {
00047                 m_sock->m_errorStatus = Environment::LastError();
00048                 throw new SocketException(Environment::LastErrorMessage());
00049         }
00050 }
00051 
00052 UdpSocket::UdpSocket( const String& address, int port )
00053 : m_sock(new Socket(0, AF_INET, SOCK_DGRAM, IPPROTO_UDP)), m_address(address), m_port(port)
00054 {
00055         memset(&m_recvFromAddr, 0, sizeof(m_recvFromAddr));
00056         
00057         m_sock->m_saAddr.sin_port = m_port;
00058         
00059         if (Char::IsDigit(m_address.CharAt(0)))
00060         {
00061                 m_sock->m_saAddr.sin_addr.s_addr = inet_addr(m_address.GetChars());
00062         }
00063         else
00064         {
00065                 hostent *phostent = gethostbyname(m_address.GetChars());
00066                 memcpy ((char *)&(m_sock->m_saAddr.sin_addr), phostent->h_addr, phostent->h_length);
00067         }
00068         
00069         SOCKADDR_IN local;
00070         local.sin_family = AF_INET;
00071         local.sin_addr.s_addr = 0;
00072         local.sin_port = 0; // choose any
00073         
00074         if (0 != ::bind(m_sock->GetFD(), (sockaddr *)&local, sizeof(local)))
00075         {
00076                 m_sock->m_errorStatus = Environment::LastError();
00077                 throw new SocketException(Environment::LastErrorMessage());
00078         }
00079 }
00080 
00081 UdpSocket::~UdpSocket()
00082 {
00083         m_sock->Close();
00084 }
00085 
00086 void UdpSocket::Send (const Array<byte>& packet)
00087 {
00088         if(packet.Length() != sendto(m_sock->GetFD(), (const char *)(byte *)packet, packet.Length(), 0, (sockaddr *)m_sock->GetAddr(), sizeof(SOCKADDR_IN)))
00089         {
00090                 m_sock->m_errorStatus = Environment::LastError();
00091                 throw new SocketException(Environment::LastErrorMessage());     
00092         }
00093 }
00094 
00095 void UdpSocket::Send(const Array<byte>& packet, const String& address)
00096 {
00097         SOCKADDR_IN addr;
00098         addr.sin_family = AF_INET;
00099         addr.sin_port = htons( m_port );
00100         
00101         if (isdigit(address.CharAt(0)))
00102         {
00103                 addr.sin_addr.s_addr = inet_addr(address.GetChars());
00104         }
00105         else
00106         {
00107                 hostent *phostent = gethostbyname(address.GetChars());
00108                 memcpy ((char *)&(addr.sin_addr), phostent->h_addr, phostent->h_length);
00109         }
00110         if (packet.Length() != sendto(m_sock->GetFD(), (const char *)(byte *)packet, packet.Length(), 0, (sockaddr *)&addr, sizeof(addr)))
00111         {
00112                 m_sock->m_errorStatus = Environment::LastError();
00113                 throw new SocketException(Environment::LastErrorMessage());     
00114         }
00115 }
00116 
00117 int UdpSocket::Recv(Array<byte>& packet)
00118 {
00119         int addrSize = sizeof(m_recvFromAddr);
00120         return recvfrom(m_sock->GetFD(), (char *)(byte *)packet, packet.Length(), 0, (sockaddr *)&m_recvFromAddr, &addrSize);
00121 }
00122 
00123 #if defined(DEBUG) || defined(_DEBUG)
00124 void UdpSocket::CheckMem() const 
00125 {
00126         m_address.CheckMem(); 
00127         m_sock.CheckMem();
00128 }
00129 
00130 void UdpSocket::ValidateMem() const 
00131 {
00132         m_address.ValidateMem(); 
00133         m_sock.ValidateMem();
00134 }
00135 #endif