udpsocket.cpp

来自「跨操作系统的微型中间件」· C++ 代码 · 共 176 行

CPP
176
字号
/*    File:       UDPSocket.cpp    Contains:   Implementation of object defined in UDPSocket.h.        */#ifndef __Win32__#include <sys/types.h>#include <sys/socket.h>#endif#include <errno.h>#include "OS.h"#include "UDPSocket.h"#include "OSThread.h"#define INVALID_FD	(-1)UDPSocket::UDPSocket(){           //setup msghdr    ::memset(&fMsgAddr, 0, sizeof(fMsgAddr));}OS_Error UDPSocket::SetRemoteAddr(UInt32 inRemoteAddr, UInt16 inRemotePort){    m_theRemoteAddr.sin_family = AF_INET;    m_theRemoteAddr.sin_port = htons(inRemotePort);    m_theRemoteAddr.sin_addr.s_addr = htonl(inRemoteAddr);        //connect to remote so that use writeV    if(fFileDesc != INVALID_FD)    {	int err = ::connect(fFileDesc, (sockaddr *)&m_theRemoteAddr, sizeof(m_theRemoteAddr));		if (err == -1)	{		return (OS_Error)OS::GetErrno();	}	fState |= kConnected;    }    return OS_NoErr;}OS_Error UDPSocket::SendTo(const char* inBuffer, UInt32 inLength){    Assert(inBuffer != NULL);        // Win32 says that inBuffer is a char*	int theErr = ::sendto(fFileDesc, inBuffer, inLength, 0, (sockaddr*)&m_theRemoteAddr, sizeof(m_theRemoteAddr));	    if (theErr == -1)        return (OS_Error)OS::GetErrno();    return OS_NoErr;}OS_Error UDPSocket::SendTo(UInt32 inRemoteAddr, UInt16 inRemotePort, void* inBuffer, UInt32 inLength){    Assert(inBuffer != NULL);        struct sockaddr_in  theTmpRemoteAddr;    theTmpRemoteAddr.sin_family = AF_INET;    theTmpRemoteAddr.sin_port = htons(inRemotePort);    theTmpRemoteAddr.sin_addr.s_addr = htonl(inRemoteAddr);    // Win32 says that inBuffer is a char*	int theErr = ::sendto(fFileDesc, (char*)inBuffer, inLength, 0, (sockaddr*)&theTmpRemoteAddr, sizeof(theTmpRemoteAddr));    if (theErr == -1)        return (OS_Error)OS::GetErrno();    return OS_NoErr;}OS_Error UDPSocket::RecvFrom(void* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen){    Assert(outRecvLen != NULL);        // Win32 says that ioBuffer is a char*    Int32 theRecvLen = ::recvfrom(fFileDesc, (char*)ioBuffer, inBufLen, 0, NULL, NULL);	    if (theRecvLen == -1)        return (OS_Error)OS::GetErrno();        Assert(theRecvLen >= 0);    *outRecvLen = (UInt32)theRecvLen;    return OS_NoErr; }OS_Error UDPSocket::RecvFrom(UInt32* outRemoteAddr, UInt16* outRemotePort,                            void* ioBuffer, UInt32 inBufLen, UInt32* outRecvLen){    Assert(outRecvLen != NULL);    Assert(outRemoteAddr != NULL);    Assert(outRemotePort != NULL);    #if __Win32__     int addrLen = sizeof(fMsgAddr);#else    socklen_t addrLen = sizeof(fMsgAddr);#endif    // Win32 says that ioBuffer is a char*    Int32 theRecvLen = ::recvfrom(fFileDesc, (char*)ioBuffer, inBufLen, 0, (sockaddr*)&fMsgAddr, &addrLen);    if (theRecvLen == -1)        return (OS_Error)OS::GetErrno();        *outRemoteAddr = ntohl(fMsgAddr.sin_addr.s_addr);    *outRemotePort = ntohs(fMsgAddr.sin_port);    Assert(theRecvLen >= 0);    *outRecvLen = (UInt32)theRecvLen;    return OS_NoErr;        }OS_Error UDPSocket::JoinMulticast(UInt32 inRemoteAddr){    struct ip_mreq  theMulti;	UInt32 localAddr = fLocalAddr.sin_addr.s_addr; // Already in network byte order    theMulti.imr_multiaddr.s_addr = htonl(inRemoteAddr);    theMulti.imr_interface.s_addr = localAddr;    int err = setsockopt(fFileDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&theMulti, sizeof(theMulti));    //AssertV(err == 0, OS::GetErrno());    if (err == -1)         return (OS_Error)OS::GetErrno();    else         return OS_NoErr;}OS_Error UDPSocket::SetTtl(UInt16 timeToLive){    // set the ttl    u_char  nOptVal = (u_char)timeToLive;//dms - stevens pp. 496. bsd implementations barf                                            //unless this is a u_char    int err = setsockopt(fFileDesc, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&nOptVal, sizeof(nOptVal));    if (err == -1)        return (OS_Error)OS::GetErrno();    else        return OS_NoErr;    }OS_Error UDPSocket::SetMulticastInterface(UInt32 inLocalAddr){    // set the outgoing interface for multicast datagrams on this socket    in_addr theLocalAddr;    theLocalAddr.s_addr = inLocalAddr;    int err = setsockopt(fFileDesc, IPPROTO_IP, IP_MULTICAST_IF, (char*)&theLocalAddr, sizeof(theLocalAddr));   // Assert(err == 0);    if (err == -1)        return (OS_Error)OS::GetErrno();    else        return OS_NoErr;    }OS_Error UDPSocket::LeaveMulticast(UInt32 inRemoteAddr){    struct ip_mreq  theMulti;    theMulti.imr_multiaddr.s_addr = htonl(inRemoteAddr);    theMulti.imr_interface.s_addr = htonl(fLocalAddr.sin_addr.s_addr);    int err = setsockopt(fFileDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&theMulti, sizeof(theMulti));    if (err == -1)        return (OS_Error)OS::GetErrno();    else        return OS_NoErr;    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?