说明
闲来无事,写了个C语言的UDP小程序,程序新建了两个线程,分别用来实现UDP数据到发送和接收。需要的直接拿去用。
上代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdbool.h>
#define MAX_UDP_RCV_LEN 512
#define LS_OK 0
#define LS_ERR -1
#define TRUE 1
#define FALSE 0
typedef struct UDP_UNICAST_ST
{
int sockfd;
struct sockaddr_in PeerAddr;
char RcvBuf[MAX_UDP_RCV_LEN];
}UdpUnicastSt;
static pthread_t keepAliveThreadId;
static UdpUnicastSt g_udpUnicast;
static pthread_t NetWorkUdpUnicastThreadId1;
static pthread_t NetWorkUdpUnicastThreadId2;
void setThreadAttr(pthread_attr_t *thread_attr, unsigned int priority, size_t stack_size)
{
size_t StackSize = 0;
pthread_attr_init(thread_attr);
pthread_attr_setscope(thread_attr, PTHREAD_SCOPE_PROCESS);
pthread_attr_setdetachstate(thread_attr, PTHREAD_CREATE_JOINABLE);
struct sched_param param;
pthread_attr_getschedparam(thread_attr, ¶m);
param.sched_priority = (int)priority;
pthread_attr_setschedparam(thread_attr, ¶m);
if(stack_size < 0x4000)
{
StackSize = 0x4000;
}
pthread_attr_setstacksize(thread_attr, StackSize);
}
void *keepAliveProcess()
{
while(1)
{
printf("udp process is alive!\n");
sleep(180);
}
}
int createThread(pthread_t *thread_id, const pthread_attr_t *attr, void *(*thread_fun) (void *), void *thread_arg)
{
int ret = -1;
ret = pthread_create(thread_id, attr, thread_fun, thread_arg);
return ret;
}
static int keepAliveThread(void)
{
int ret = -1;
pthread_attr_t Thread_Attr;
setThreadAttr(&Thread_Attr, 11, 0x8000);
ret = createThread(&keepAliveThreadId, &Thread_Attr, keepAliveProcess, NULL);
if(ret != 0)
{
printf("keepAliveThread failed!\n");
}
return ret;
}
void threadWaitDone(void **reval)
{
pthread_join(keepAliveThreadId, reval);
}
int UdpUnicastInit()
{
int ret = -1;
g_udpUnicast.sockfd = socket(AF_INET,SOCK_DGRAM, 0);
if (g_udpUnicast.sockfd < 0)
{
printf("Create UDP socket failed!\n");
return LS_ERR;
}
struct sockaddr_in LocalAddr;
memset(&LocalAddr, 0, sizeof(struct sockaddr_in));
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons(13903);
LocalAddr.sin_addr.s_addr = INADDR_ANY;
ret = bind(g_udpUnicast.sockfd, (struct sockaddr *)(&LocalAddr), sizeof(struct sockaddr));
if (-1 == ret)
{
close(g_udpUnicast.sockfd);
g_udpUnicast.sockfd = -1;
return LS_ERR;
}
return LS_OK;
}
void modbusMsgPrint(unsigned char *pBuffer, int buffLen, bool bRcvFlag)
{
if(NULL == pBuffer || 0 == buffLen)
{
return;
}
char szPrint[4096] = {0};
int i = 0;
for(i = 0;i < buffLen; i++)
{
snprintf(&(szPrint[strlen(szPrint)]),4096 - strlen(szPrint)," 0x%02X",pBuffer[i]);
}
if(bRcvFlag)
{
printf("Rcv:%s.\n",szPrint);
}
else
{
printf("Send:%s.\n",szPrint);
}
}
void* NetWorkUdpUnicastSendThread(void *param)
{
socklen_t addrLen = 0;
unsigned char sendBuff[64] = {1,1,2,2,3,3,4,4,5};
int recvRet = 0;
struct sockaddr_in LocalAddr;
addrLen = sizeof(struct sockaddr);
memset(&LocalAddr, 0, sizeof(struct sockaddr_in));
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons(13903);
printf("start NetWorkUdpUnicastSendThread....!\n");
while(1)
{
LocalAddr.sin_addr.s_addr = inet_addr("192.168.8.28");
recvRet = (int)sendto(g_udpUnicast.sockfd, sendBuff, 11, 0, (struct sockaddr*)&LocalAddr, addrLen);
printf("UDP send %d data: %s\n", recvRet, sendBuff);
modbusMsgPrint(sendBuff, recvRet, FALSE);
sleep(60);
}
}
void* NetWorkUdpUnicastRecvThread(void *param)
{
int recvRet = -1;
socklen_t addrLen = 0;
addrLen = sizeof(struct sockaddr);
printf("start NetWorkUdpUnicastRecvThread....!\n");
while(1)
{
recvRet = (int)recvfrom(g_udpUnicast.sockfd, g_udpUnicast.RcvBuf, MAX_UDP_RCV_LEN - 1,0,(struct sockaddr*)(&g_udpUnicast.PeerAddr),&addrLen);
if (-1 == recvRet)
{
printf("UDP recv data failed!\n");
continue;
}
printf("UDP recv %d data: %s\n", recvRet, g_udpUnicast.RcvBuf);
modbusMsgPrint((unsigned char *)g_udpUnicast.RcvBuf, recvRet, TRUE);
}
}
int netWorkUdpUnicastInit()
{
int ret = -1;
pthread_attr_t Thread_Attr1;
pthread_attr_t Thread_Attr2;
memset(&g_udpUnicast, 0,sizeof(UdpUnicastSt));
ret = UdpUnicastInit();
if(LS_OK != ret)
{
printf("UDP Socket init failed!\n");
return LS_ERR;
}
setThreadAttr(&Thread_Attr1,20,0x8000);
ret = createThread(&NetWorkUdpUnicastThreadId1, &Thread_Attr1, NetWorkUdpUnicastSendThread, NULL);
if(ret != 0)
{
printf("Create network udp send thread failed!\n");
return LS_ERR;
}
setThreadAttr(&Thread_Attr2,20,0x8000);
ret = createThread(&NetWorkUdpUnicastThreadId2, &Thread_Attr2, NetWorkUdpUnicastRecvThread, NULL);
if(ret != 0)
{
printf("Create network udp recv thread failed!\n");
return LS_ERR;
}
return LS_OK;
}
int main()
{
printf("---udp process start---\n");
void *thread_reval = NULL;
netWorkUdpUnicastInit();
keepAliveThread();
threadWaitDone(&thread_reval);
if(thread_reval != NULL)
{
printf("thread_reval : %s is not null\n", (char *)thread_reval);
}
printf("---udp process end---\n");
return 0;
}
运行结果
linux环境下运行进程或者直接QT编译运行,这里的结果展示为centos虚拟机的QT运行。
虚拟机ip为192.168.8.235,程序里UDP的端口写死的13903。
宿主机的ip为192.168.8.28,运行一个UDP的模拟工具。
本程序定时发送一串字节流,模拟工具可以正常接收。
模拟工具发送字节流,程序也可以正常接收显示。
打完收工。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)