⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udpsocket.cpp

📁 网络socket,IO,线程池
💻 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 + -