📄 udpsocket.cpp
字号:
/*
2003 by zhy
*/
#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"Ws2_32")
#include "UdpSocket.h"
using namespace NET;
#include "../include/exception.h"
using namespace CommonInclude;
////////////////////////////////////////////////////////////////////////////
// Constructors / Destructor //
////////////////////////////////////////////////////////////////////////////
// Constructor
CUdpSocket::CUdpSocket(SOCKET sock) : CSocketBase(sock,sock == INVALID_SOCKET ? CSocketBase::STATE_CLOSE : CSocketBase::STATE_OPEN),
m_timeout(1),m_timeoutU(0),m_isserver(false)
{
m_length = sizeof(m_peeradd);
memset(&m_peeradd, 0, sizeof(m_peeradd));
m_peeradd.sin_family = AF_INET;
}
// Destructor
CUdpSocket::~CUdpSocket()
{
Close();
}
////////////////////////////////////////////////////////////////////////////
// Operations //
////////////////////////////////////////////////////////////////////////////
bool CUdpSocket::Listen(unsigned short uPort,unsigned long ip)
{
Close();
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return false;
int opt = 1;
setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
struct sockaddr_in peer;
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
//peer.sin_addr.s_addr = htonl(ip);
peer.sin_addr.s_addr = ip;
peer.sin_port = htons(uPort);
if (bind(m_sock, (struct sockaddr *)&peer, sizeof(peer)))
{
Close();
return false;
}
m_isserver = true;
CSocketBase::SetStateBit(CSocketBase::STATE_OPEN);
return true;
}
bool CUdpSocket::Connectbroadcast(unsigned short uPort)
{
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return false;
memset(&m_peeradd, 0, sizeof(m_peeradd));
m_peeradd.sin_family = AF_INET;
m_peeradd.sin_addr.s_addr = INADDR_BROADCAST;
m_peeradd.sin_port = htons(uPort);
m_isserver = false;
int opt = 1;
if(setsockopt(m_sock, SOL_SOCKET, SO_BROADCAST,(char *)&opt, (int)sizeof(opt)))
{
Close();
return false;
}
else
CSocketBase::SetStateBit(CSocketBase::STATE_OPEN);
return true;
}
bool CUdpSocket::Connect(const string& IP, unsigned short uPort)
{
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return false;
memset(&m_peeradd, 0, sizeof(m_peeradd));
m_peeradd.sin_family = AF_INET;
m_peeradd.sin_addr = GetIPAddr(IP.c_str());
m_peeradd.sin_port = htons(uPort);
m_isserver = false;
CSocketBase::SetStateBit(CSocketBase::STATE_OPEN);
return true;
}
////////////////////////////////////////////////////////////////////////////
// About the Multicast //
////////////////////////////////////////////////////////////////////////////
bool CUdpSocket::Supportmuticast(unsigned long ip,unsigned short port)
{
m_sock = WSASocket(AF_INET, SOCK_DGRAM, 0,(LPWSAPROTOCOL_INFO)NULL, 0,
WSA_FLAG_MULTIPOINT_C_LEAF| WSA_FLAG_MULTIPOINT_D_LEAF);
if(INVALID_SOCKET == m_sock)
return false;
int opt = 1;
setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
struct sockaddr_in peer;
memset(&peer, 0, sizeof(peer));
peer.sin_family = AF_INET;
peer.sin_addr.s_addr = INADDR_ANY;
peer.sin_port = htons(port);
if (bind(m_sock, (struct sockaddr *)&peer, sizeof(peer)))
{
Close();
return false;
}
//peer.sin_addr.s_addr = htonl(ip);
peer.sin_addr.s_addr = ip;
BOOL nLoopBack= TRUE;
WSAIoctl(m_sock,SIO_MULTIPOINT_LOOPBACK,&nLoopBack,sizeof(nLoopBack), 0,0,0,0,0);
SOCKET newsock = WSAJoinLeaf(m_sock,(sockaddr*)&peer,sizeof(peer),0,0,0,0,JL_BOTH);
if( INVALID_SOCKET == newsock)
return false;
else
{
m_isserver = true;
return true;
}
}
////////////////////////////////////////////////////////////////////////////
// 多播的发送跟普通发送一样,先connect,然后write,但可以调用write之前设置存活时间,
// 存活时间每经过一个路由减一
// TTL阈值(Threshold) Description
// TTL equal to 0 Restricted to the same host
// TTL equal to 1 Restricted to the same subnet
// TTL equal to 32 Restricted to the same site
// TTL equal to 64 Restricted to the same region
// TTL equal to 128 Restricted to the same continent
// TTL equal to 255 Unrestricted in scope
////////////////////////////////////////////////////////////////////////////
bool CUdpSocket::SetTTL(unsigned char TTL)
{
if( 0 == WSAIoctl(m_sock,SIO_MULTICAST_SCOPE,&TTL,sizeof(unsigned char),0,0,0,0,0))
return true;
else
return false;
}
////////////////////////////////////////////////////////////////////////////
// the Main R/W Operation //
////////////////////////////////////////////////////////////////////////////
// Write
int CUdpSocket::Write(const void *buf, size_t len)
{
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return -1;
return ::sendto(m_sock, (const char*)buf, len, 0, (struct sockaddr *)&m_peeradd, sizeof(m_peeradd));
}
// Read
int CUdpSocket::Read(void *buf, size_t len)
{
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return -1;
if (m_timeout != 0 || m_timeoutU != 0)
{
int res = SocketTimeCheck(m_sock,1,m_timeout,m_timeoutU);
if (res != 0)
return res;
}
if (m_isserver)
return ::recvfrom(m_sock, (char *)buf, len, 0 , (struct sockaddr *)&m_peeradd, &m_length);
return ::recvfrom(m_sock, (char *)buf, len, 0 , NULL, NULL);
}
// Peek
int CUdpSocket::Peek(void *buf, size_t len)
{
if (!Initsocket(AF_INET, SOCK_DGRAM, 0))
return -1;
if (m_timeout != 0 && m_timeoutU != 0)
{
int res = SocketTimeCheck(m_sock,1,m_timeout,m_timeoutU);
if (res != 0)
return res;
}
if (m_isserver)
return ::recvfrom(m_sock, (char *)buf, len, MSG_PEEK , (struct sockaddr *)&m_peeradd, &m_length);
return ::recvfrom(m_sock, (char *)buf, len, MSG_PEEK , NULL, NULL);
}
////////////////////////////////////////////////////////////////////////////
// About Close Operations //
////////////////////////////////////////////////////////////////////////////
void CUdpSocket::Close()
{
CSocketBase::Close();
}
void CUdpSocket::Shutdown()
{
CSocketBase::Shutdown();
}
void CUdpSocket::Onlyclose()
{
CSocketBase::Onlyclose();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -