栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言实现udp客户端

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言实现udp客户端

C语言实现udp客户端,子线程轮询接收数据,QT的界面框架,QMainWindow使用回调函数接收数据,支持windows和linux跨平台。

QMainWindow调用udp

///接收数据回调函数
void udpReceiveMsg(char *data, int32_t nb_data, void *user)
{
    MainWindow * mw = (MainWindow*)user;
    if(mw == nullptr) return;
    mw->UdpRevMsgCallBack(data,nb_data);
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    UdpHandle *pUdpHandle = (UdpHandle *)malloc(sizeof(UdpHandle));
    pUdpHandle->receive = udpReceiveMsg;
    pUdpHandle->user = this;

    udp_create(pUdpHandle,(char*)"192.168.72.35",9000,9090);
    udp_start(pUdpHandle);
}

MainWindow::~MainWindow()
{
    udp_destroy(pUdpHandle);
    delete ui;
}

///接收数据处理
void MainWindow::UdpRevMsgCallBack(char *data, int32_t nb_data)
{
    QByteArray array(data,nb_data);
    qDebug()<<"["<<__FILE__<<"]"<<__LINE__<<__FUNCTION__<<" "<
    udp_sendData(pUdpHandle,ui->textEdit->toPlainText().toLatin1().data(),ui->textEdit->toPlainText().size());
}

UdpClient.h

#ifndef UDPHANDLE_H_
#define UDPHANDLE_H_

#include 
#include 

#ifdef _WIN32
#include 
#include 
//#define SOCKADDR_IN
#define socklen_t int
#else

#include 
#include 
#include 
#endif

typedef struct {
    int32_t fd;
    int32_t localPort;
    int32_t remotePort;
    int32_t isStart;
    int32_t isLoop;
    int32_t notRemoteInit;
    pthread_t threadId;

    //char serverIp[30];
    void* user;
    struct sockaddr_in local_addr;
    struct sockaddr_in remote_addr;
    void (*receive)(char *data, int32_t nb_data,void* user);
    void (*startStunTimer)(void* user);
}UdpHandle;

#ifdef __cplusplus
extern "C"{
#endif
int32_t udp_create(UdpHandle* udp,char* remoteIp,int32_t remotePort,int32_t plocalPort);//创建udp套接字
void udp_destroy(UdpHandle* udp);//销毁套接字
void udp_start(UdpHandle* udp);//创建线程,启动udp
void udp_stop(UdpHandle* udp);//停止线程处理函数
int32_t udp_sendData(UdpHandle* udp,char* p,int32_t plen);//udp发送数据
#ifdef __cplusplus
}
#endif
#endif

UdpClient.c

#include 
#include 
#include 
#include 

#include "UdpClient.h"
#ifndef _WIN32
#define GetSockError()	errno
#define SetSockError(e)	errno = e

#define closesocket(s)	close(s)
#endif


int32_t udp_create(UdpHandle *udp, char *remoteIp,int32_t remotePort,int32_t plocalPort)
{
    if (udp == NULL)		return -1;
	udp->localPort = plocalPort;
	udp->fd = -1;
	udp->remotePort = remotePort;

#ifdef _WIN32
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORd(2, 2);
    WSAStartup(wVersionRequested, &wsaData);//初始化socket库
#endif

	udp->local_addr.sin_family = AF_INET;
	udp->local_addr.sin_port = htons(udp->localPort);
	udp->local_addr.sin_addr.s_addr = INADDR_ANY;
    
    udp->fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(udp->fd < 0)
    {
#ifdef _WIN32
        printf("create socket error,udp->fd=%d,WSAGetLastError=%dn",udp->fd,WSAGetLastError());///WSAGetLastError返回当前错误码,windowsAPI
#else
        printf("create socket error,udp->fd=%dn",udp->fd);
        perror("error:");///linuxAPI,打印输出上一个函数发生的错误,"error:"会首先打印
#endif
        return -1;
    }

	udp->remote_addr.sin_family = AF_INET;
    
	udp->remote_addr.sin_port = htons(udp->remotePort);
    printf("udp->remote_addr.sin_port=%dn",udp->remote_addr.sin_port);
	udp->notRemoteInit=remotePort>0?0:1;

    
#ifdef _WIN32
    udp->remote_addr.sin_addr.S_un.S_addr=inet_addr(remoteIp);
#else
	udp->remote_addr.sin_addr.s_addr = inet_addr(remoteIp);
#endif
    return 0;
}

void udp_destroy(UdpHandle *udp)
{
    if (udp == NULL)
        return;
    udp_stop(udp);
    if (udp->fd > 0)
    {
        
        closesocket(udp->fd);
        udp->fd = -1;
    }
}


int32_t udp_sendData(UdpHandle *udp, char *data, int32_t nb)
{
    if (udp == NULL || !udp->isStart || udp->notRemoteInit || data==NULL)	return -1;
    return sendto(udp->fd, data, nb, 0, (struct sockaddr*) &udp->remote_addr,sizeof(struct sockaddr)) > 0 ? 0 : 1;

    
}


void* run_udp_thread(void *obj)
{
    UdpHandle *udp = (UdpHandle*) obj;
	udp->isStart = 1;

    
#ifdef _WIN32
    int32_t timeout=200;
    setsockopt(udp->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timeout,  sizeof(timeout));
#else
	struct timeval tv;
	tv.tv_sec = 0;
	tv.tv_usec = 200000;  // 200 ms
	setsockopt(udp->fd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv,	sizeof(struct timeval));
#endif
    printf("udp server is starting,localPort=%dn", udp->localPort);

    
    if (bind(udp->fd, (struct sockaddr*) &udp->local_addr,sizeof(struct sockaddr_in)) < 0)
    {
        printf("Udp server bind errorn");
        #ifdef _WIN32
        printf("WSAGetLastError=%dn",WSAGetLastError());
        #else
        perror("error:");
        #endif
        return NULL;
	}

	char buffer[2048] = { 0 };
	udp->isLoop = 1;

	int32_t len = 0;
//	if (!udp->notRemoteInit&&udp->startStunTimer)	udp->startStunTimer(udp->user);
	socklen_t src_len = sizeof(struct sockaddr_in);

    while (udp->isLoop)
    {
		struct sockaddr_in src;
		memset(&src, 0, src_len);
		memset(buffer, 0, 2048);
        
        if ((len = recvfrom(udp->fd, buffer, 2048, 0,	(struct sockaddr*) &src, &src_len)) > 0)
        {
            if(udp->notRemoteInit)
            {
				udp->remotePort = ntohs(src.sin_port);
				udp->remote_addr.sin_port = src.sin_port;//htons(udp->remotePort);

#ifdef _WIN32
				udp->remote_addr.sin_addr.S_un.S_addr=src.sin_addr.S_un.S_addr;
#else
				udp->remote_addr.sin_addr.s_addr = src.sin_addr.s_addr;
#endif

				udp->notRemoteInit=0;
				//if (udp->startStunTimer)	udp->startStunTimer(udp->user);
			}
			if (udp->receive)	udp->receive(buffer, len, udp->user);
		}
	}
	udp->isStart = 0;
    closesocket(udp->fd);
	udp->fd = -1;

	return NULL;
}


void udp_start(UdpHandle *udp)
{
	if (udp == NULL)	return;
    if (pthread_create(&udp->threadId, 0, run_udp_thread, udp))
    {
        printf("start could not start threadn");
	}
}


void udp_stop(UdpHandle *udp)
{
	if (udp == NULL)	return;
	udp->isLoop = 0;
	while (udp->isStart)
        usleep(1000);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928138.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号