在项目中遇到个硬件厂家,用的UDP协议。由于,现场需求是要检测设备的状态,而UDP是一个不可靠的协议,只能通过接收他收到指令的返回值来判断当前状态,这就需要我们在发送指令后监听接收。而且,我们不可能一直死等接收结果,所以我们需要写一个非阻塞的接收。
直接上代码:
CUdp.h
#ifndef _UDP_H
#define _UDP_H
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <algorithm>
class CUdpEx
{
public:
CUdpEx(void);
~CUdpEx(void);
public:
static bool SendUdpData(const char* lpszIP, int nPort, const char *pData, int nLen);
bool revUdpData();
};
#endif
CUdp.cpp
#include "UdpEx.h"
static SOCKET g_hSocket = 0;
void Perror(const char *s)
{
perror(s);
exit(EXIT_FAILURE);
}
static void setnonblocking(int sockfd)
{
int flag = fcntl(sockfd, F_GETFL, 0);
if (flag < 0)
{
Perror("fcntl F_GETFL fail");
return;
}
if (fcntl(sockfd, F_SETFL, flag | O_NONBLOCK) < 0)
{
Perror("fcntl F_SETFL fail");
}
}
bool CUdpEx::SendUdpData(const char* lpszIP, int nPort, const char *pData, int nLen)
{
struct sockaddr_in addrRecv;
addrRecv.sin_family = AF_INET;
addrRecv.sin_port = htons(nPort);
addrRecv.sin_addr.s_addr = inet_addr(lpszIP);
int nSended = sendto(g_hSocket,
pData,
nLen,
0,
(sockaddr*) &addrRecv,
(int)sizeof(addrRecv));
return (nSended == nLen);
}
bool CUdpEx::revUdpData()
{
bool ret=false;
struct sockaddr_in cliaddr;
socklen_t len;
long tempCount = GetCurrentSeconds();
for ( ; ; )
{
char mesg[1024] = {};
int n = recvfrom(g_hSocket, mesg, 1024, 0, (sockaddr *)&cliaddr, &len);
sleep(1);
if (n>0)
{
ret = true;
break;
}
else
{
if (GetCurrentSeconds()-tempCount>ONE_SECONDS_1000_MS*8)
{
DPLOG_INFO("UDP","发送指令失败"<<errno);
break;
}
}
}
return ret;
}
CUdpEx::CUdpEx(void)
{
if (g_hSocket==0)
{
g_hSocket = socket(AF_INET,SOCK_DGRAM,0);
assert(g_hSocket != -1);
setnonblocking(g_hSocket);
}
}
CUdpEx::~CUdpEx(void)
{
close(g_hSocket);
g_hSocket = 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)