bool RawDatagramSocket::send(InetAddress &addr, Datagram &datagram) { if (!m_isOpen) return false; if (!addr.isValid()) return false; // Build up this address struct sockaddr_in address; memset((char*) &address, 0, sizeof(struct sockaddr_in)); address.sin_family = AF_INET; address.sin_addr = addr.getIPAddress(); address.sin_port = 0; char* buffer = 0; unsigned int bufSize = datagram.GetBuffer(&buffer); // Do the actual send int sent = sendto(m_socket, buffer, bufSize, 0, (sockaddr*) &address, sizeof(sockaddr)); // Test for send errorrs if (sent == -1) { // error in transmission return false; } else if (sent != (int) bufSize) { // not all datagram sent return false; } return true; }
bool RawDatagramSocket::receive(InetAddress &outAddr, Datagram &outDG) { // The return address information sockaddr_in addr; int numBytes = 0; #ifdef WIN32 int sas = sizeof(sockaddr); #else socklen_t sas = sizeof(sockaddr); #endif // Read pending datagram if (!m_stripHeader) { // if we don't have to strip it's much more efficient as we can // simply use the datagram's buffer directly char* buffer = 0; outDG.GetBuffer(&buffer); outDG.SetBuffer(0, Datagram::MaxDatagramSize); numBytes = recvfrom(m_socket, buffer, Datagram::MaxDatagramSize, 0, (sockaddr *) &addr, &sas); if (numBytes < 0) { outDG.SetBuffer(0, 0); return false; } outDG.SetBuffer(0, numBytes); } else { // stripping means we must have a temp buffer and pay for it :P char buffer[Datagram::MaxDatagramSize + sizeof(ip)]; numBytes = recvfrom (m_socket, buffer, Datagram::MaxDatagramSize + sizeof(ip), 0, (sockaddr *) &addr, &sas); if (numBytes < 0) { outDG.SetBuffer(0, 0); return false; } // Find the number of bytes for the header of the message (the payload is // immediately after) ip *ipstr = (ip*) buffer; int hlen = ipstr->ip_hl << 2; // 32-bit "words" // hopefully payload has zero or more bytes... if (numBytes < hlen) { outDG.SetBuffer(0, 0); return false; } outDG.SetBuffer(buffer + hlen, numBytes - hlen); } outAddr.setIPAddress(addr.sin_addr); return true; }