UdpSocete.h
/*__________________________UDP-Client__________________________________*/
class UdpClient
{
public:
UdpClient();
UdpClient(const std::string& IP, int Port);
~UdpClient();
public:
bool Connect(bool bMutex = false) override;
void DisConnect(bool bMutex = false) override;
bool clearBuf_c();
bool recvBuf_c(char* pStr, int& len, int waitTimeMS = 0) override;
bool sendBuf_c(char const *pStr, const int& len) override;
protected:
bool Connect(std::string IP, int Port);
private:
SOCKET m_socket;
SOCKADDR_IN m_addrServer;
};
/*__________________________UDP-Server__________________________________*/
class UdpServer
{
public:
UdpServer();
UdpServer(const std::string& IP, int Port);
~UdpServer();
public:
bool Connect(bool bMutex = false) override;
void DisConnect(bool bMutex = false) override;
bool clearBuf_c();
bool recvBuf_c(char* pStr, int& len, int waitTimeMS = 0) override;
bool sendBuf_c(char const *pStr, const int& len) override;
protected:
bool Connect(std::string IP, int Port);
private:
SOCKET m_socket;
SOCKADDR_IN m_addrServer;
SOCKADDR_IN m_addrClient;
std::list<SOCKADDR_IN> m_socketClientList;
};
UdpSocete.cpp
/*__________________________UDP-Client__________________________________*/
UdpClient::UdpClient(void)
{
m_socket = SOCKET_ERROR;
m_typeName = "UDP-服务器";
}
UdpClient::UdpClient(const std::string& IP, int Port)
: ISocketBaese(IP, Port, SOCKET_TYPE_UDP_CLINET)
{
m_socket = SOCKET_ERROR;
m_typeName = "UDP-服务器";
}
UdpClient::~UdpClient(void)
{
}
bool UdpClient::Connect(bool bMutex)
{
if (bMutex)
{
QMutexLocker locker(&m_Mutex);
return Connect(m_IP, m_Port);
}
return Connect(m_IP, m_Port);
}
bool UdpClient::Connect(std::string IP, int Port)
{
DisConnect();
char strIp[1024];
memset(strIp, '\0', 1024);
memcpy(strIp, IP.c_str(), IP.length());
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);//该函数的功能是加载一个Winsocket库版本
if (err != 0)
return false;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
DisConnect();
return false;
}
m_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (m_socket == INVALID_SOCKET)
{
DisConnect();
return false;
}
u_long u1 = 1;
if (SOCKET_ERROR == ioctlsocket(m_socket, FIONBIO, &u1))
{
DisConnect();
return false;
}
memset((char*)&m_addrServer, 0, sizeof(m_addrServer));
m_addrServer.sin_addr.S_un.S_addr = inet_addr(strIp);
m_addrServer.sin_family = AF_INET;
m_addrServer.sin_port = htons(Port);
//memset((char*)&m_addrClient, 0, sizeof(m_addrClient));
//m_addrClient.sin_addr.S_un.S_addr = inet_addr(strIp);
//m_addrClient.sin_family = AF_INET;
//m_addrClient.sin_port = htons(Port);
//int rtn = bind(m_socket, (sockaddr*)&m_addrClient, sizeof(m_addrClient));
//if (rtn != 0)
//{
// return false;
//}
m_bConnectOK = true;
return true;
}
void UdpClient::DisConnect(bool bMutex)
{
if (m_socket != SOCKET_ERROR)
{
closesocket(m_socket);
//WSACleanup();
}
m_bConnectOK = false;
m_socket = SOCKET_ERROR;
}
bool UdpClient::clearBuf_c()
{
bool rtn = 0;
SOCKADDR_IN temp_in;
int formLen = sizeof(SOCKADDR_IN);
do
{
if (recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen) <= 0)
break;
} while (1);
return true;
}
bool UdpClient::recvBuf_c(char* pStr, int& len, int waitTimeMS)
{
QMutexLocker locker(&m_Mutex);
memset(m_recvBuffer, '\0', CHAR_LEN);
int buflen;
SOCKADDR_IN temp_in;
int formLen = sizeof(SOCKADDR_IN);
DWORD initTime = GetTickCount();
while (true)
{
buflen = recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen);
if (buflen > 0)
{
if (m_addrServer.sin_addr.S_un.S_addr != temp_in.sin_addr.S_un.S_addr\
|| m_addrServer.sin_port != temp_in.sin_port)
return false;
memcpy(pStr, m_recvBuffer, buflen);
len = buflen;
return true;
}
//当接受数据时断开连接会返回0
else if (buflen == 0)
{
m_bConnectOK = false;
Connect();
return false;
}
//初始等待连接或是已连接未收到数据返回-1
else if (buflen < 0)
{
if (!m_bConnectOK)
Connect();
if (abs(int(GetTickCount() - initTime)) > waitTimeMS)
return false;
}
}
return true;
}
bool UdpClient::sendBuf_c(char const *pStr, const int& len)
{
QMutexLocker locker(&m_Mutex);
int rtn = sendto(m_socket, pStr, len, 0, (sockaddr*)&m_addrServer, sizeof(SOCKADDR_IN));
if (rtn < 0)
{
return false;
}
return true;
}
/*__________________________UDP-Server__________________________________*/
UdpServer::UdpServer(void)
{
m_socket = SOCKET_ERROR;
m_typeName = "UDP-服务器";
}
UdpServer::UdpServer(const std::string& IP, int Port)
: ISocketBaese(IP, Port, SOCKET_TYPE_UDP_SERVER)
{
m_socket = SOCKET_ERROR;
m_typeName = "UDP-服务器";
}
UdpServer::~UdpServer(void)
{
}
bool UdpServer::Connect(bool bMutex)
{
if (bMutex)
{
QMutexLocker locker(&m_Mutex);
return Connect(m_IP, m_Port);
}
return Connect(m_IP, m_Port);
}
bool UdpServer::Connect(std::string IP, int Port)
{
DisConnect();
char strIp[1024];
memset(strIp, '\0', 1024);
memcpy(strIp, IP.c_str(), IP.length());
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);//该函数的功能是加载一个Winsocket库版本
if (err != 0)
return false;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
{
DisConnect();
return false;
}
m_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (m_socket == INVALID_SOCKET)
{
DisConnect();
return false;
}
u_long u1 = 1;
if (SOCKET_ERROR == ioctlsocket(m_socket, FIONBIO, &u1))
{
DisConnect();
return false;
}
//memset((char*)&m_addrOtherSide, 0, sizeof(m_addrOtherSide));
//m_addrOtherSide.sin_addr.S_un.S_addr = inet_addr(strIp);
//m_addrOtherSide.sin_family = AF_INET;
//m_addrOtherSide.sin_port = htons(Port);
memset((char*)&m_addrServer, 0, sizeof(m_addrServer));
m_addrServer.sin_addr.S_un.S_addr = inet_addr(strIp);
m_addrServer.sin_family = AF_INET;
m_addrServer.sin_port = htons(Port);
int rtn = bind(m_socket, (sockaddr*)&m_addrServer, sizeof(m_addrServer));
if (rtn != 0)
{
return false;
}
//sockaddr addr;
//sockaddr_in* addr_v4;
//int addr_len = sizeof(addr);
//getsockname(m_socket, &addr, &addr_len);
//addr_v4 = (sockaddr_in*)(&addr);
m_bConnectOK = true;
return true;
}
void UdpServer::DisConnect(bool bMutex)
{
if (m_socket != SOCKET_ERROR)
{
closesocket(m_socket);
//WSACleanup();
}
m_socketClientList.clear();
m_bConnectOK = false;
m_socket = SOCKET_ERROR;
}
bool UdpServer::clearBuf_c()
{
bool rtn = 0;
SOCKADDR_IN temp_in;
int formLen = sizeof(SOCKADDR_IN);
do
{
if (recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen) <= 0)
break;
} while (1);
return true;
}
bool UdpServer::recvBuf_c(char* pStr, int& len, int waitTimeMS)
{
QMutexLocker locker(&m_Mutex);
memset(m_recvBuffer, '\0', CHAR_LEN);
int buflen;
SOCKADDR_IN temp_in;
int formLen = sizeof(SOCKADDR_IN);
DWORD initTime = GetTickCount();
while (true)
{
buflen = recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen);
if (buflen > 0)
{
bool addFlag = 0;
for (auto&it : m_socketClientList)
{
if (it.sin_addr.S_un.S_addr == temp_in.sin_addr.S_un.S_addr\
&& it.sin_port == temp_in.sin_port)
addFlag = 1;
}
if (addFlag == 0)
m_socketClientList.push_back(temp_in);
m_addrClient = temp_in;
memcpy(pStr, m_recvBuffer, buflen);
len = buflen;
return true;
}
//当接受数据时断开连接会返回0
else if (buflen == 0)
{
m_bConnectOK = false;
Connect();
return false;
}
//初始等待连接或是已连接未收到数据返回-1
else if (buflen < 0)
{
if (!m_bConnectOK)
Connect();
if (abs(int(GetTickCount() - initTime)) > waitTimeMS)
return false;
}
}
return true;
}
bool UdpServer::sendBuf_c(char const *pStr, const int& len)
{
QMutexLocker locker(&m_Mutex);
int rtn = sendto(m_socket, pStr, len, 0, (sockaddr*)&m_addrClient, sizeof(SOCKADDR_IN));
if (rtn < 0)
{
return false;
}
return true;
}