LabWindows网络通讯程序例子(UDP)

UDP相关知识

1.对于UDP回调函数UDPCallback的UDP_DATAREADY事件,每次datagram达到时,都会产生回调事件("This event is received once per datagram that arrives")

2.无论使用单点发送(unicast)、多点发送(multicast)、广播发送(broadcast),都是使用UDPWrite()函数,只是地址(destinationAddress)不同,unicast为接收机的IP地址,multicast地址范围224.0.0.0~239.255.255.255,broadcast地址:255.255.255.255.("When selecting a multicast address for your application to use, avoid the range 224.0.0.0 to 224.0.0.255; this range is reserved for local network administrative and maintenance purposes.")

3.对于UDPRead函数,"If you pass 0 for inputBuffer or inputBufferSize, the function peeks at the port and returns the size of the first available datagram."

4.RadioGroup控件,记得在“Edit Item(s)”中修改每一项的值。否则默认都为0.

5.Labview软件UDP发送字符串时,没有发送字符串结束标志null,若已CVI相通信,得自己手动加入字符串结束标志位(十六进制显示00)。

 

UDP程序流程图

 

//Reader


#include <udpsupp.h>
#include <ansi_c.h>
#include <cvirte.h>		
#include <userint.h>
#include "Read.h"
#define LOCAL_PORT 60100	           //定义本地UDP端口
#define MULTICAST_ADDRESS "228.0.1.1"      //多点传播地址

static int panelHandle;
static unsigned int UDPReadHandle=0;       //UDP连接ID

int CVICALLBACK UDPReadCallBack (unsigned channel, int eventType, int errCode, void *callbackData);

int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)
		return -1;	/* out of memory */
	if ((panelHandle = LoadPanel (0, "Read.uir", PANEL)) < 0)
		return -1;
	DisplayPanel (panelHandle);
    
	SetCtrlVal(panelHandle,PANEL_NUMERIC,LOCAL_PORT);      //显示本地UDP端口
	SetCtrlVal(panelHandle,PANEL_STRING,MULTICAST_ADDRESS);//显示多点传送地址
	CreateUDPChannelConfig (LOCAL_PORT, UDP_ANY_ADDRESS, 1, UDPReadCallBack, 0,& UDPReadHandle);  //打开UDP端口
	
	RunUserInterface ();
	
	if(UDPReadHandle)
	{
	  DisposeUDPChannel (UDPReadHandle);   //关闭UDP端口
	}
	DiscardPanel (panelHandle);
	return 0;
}
//是否订阅MULTICAST的回调函数
int CVICALLBACK SubscribMulticast (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{   int value;
	switch (event)
	{
		case EVENT_COMMIT:
			GetCtrlVal(panelHandle,PANEL_CHECKBOX,& value);   //读取是否打钩
			if(value)   //若打钩,则订阅
			{
			 UDPMulticastSubscribe (UDPReadHandle, MULTICAST_ADDRESS, NULL);
			}	
			else     //无打钩,则退订
			{
			 UDPMulticastUnsubscribe (UDPReadHandle, MULTICAST_ADDRESS, NULL);
			}
			
			break;
	}
	return 0;
}
//关闭面板
int CVICALLBACK panelCB (int panel, int event, void *callbackData,
		int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_CLOSE:
			QuitUserInterface(0);    
			break;
	}
	return 0;
}
//UDP接收到数据时的回调函数
int CVICALLBACK UDPReadCallBack (unsigned channel, int eventType, int errCode, void *callbackData)
{
	int size;     //datagram的大小
	char * receiveData; //接收到的数据
	int sourcePort;  
	char sourceAddress[16];
	char sourceString[16+20];  
	switch(eventType)
	{
	   case UDP_DATAREADY:
		   //If you pass 0 for inputBuffer or inputBufferSize, 
                   //the function peeks at the port and returns the size of the first available datagram

		   size = UDPRead (UDPReadHandle, 0, 0, UDP_DEFAULT_TIMEOUT, 0, 0);
		   receiveData=(char *)malloc(size*sizeof(char));
		   size = UDPRead (UDPReadHandle, receiveData, size,  UDP_DO_NOT_WAIT, & sourcePort, sourceAddress);
		   sprintf(sourceString, "[%s:%d]: ", sourceAddress, sourcePort);
		   SetCtrlVal(panelHandle,PANEL_TEXTBOX,sourceString);	   //输出发送端的IP和端口号
		   SetCtrlVal(panelHandle,PANEL_TEXTBOX,receiveData);
		   SetCtrlVal(panelHandle,PANEL_TEXTBOX,"\n");
		   
		   free(receiveData);
		   break;
	}
	return 0;
}

//Writer

#include <ansi_c.h>
#include <udpsupp.h>
#include "radioGroup.h"
#include <cvirte.h>		
#include <userint.h>
#include "Write.h"
#define MULTICAST_ADDRESS "228.0.1.1"	 //定义多点传播地址
//广播发送地址为常量UDP_LAN_BROADCAST_ADDR

static int panelHandle;
unsigned int UDPWriteHandle=0;  //UDP端口连接ID
unsigned int localPort;		    //UDP端口号

int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)
		return -1;	/* out of memory */
	if ((panelHandle = LoadPanel (0, "Write.uir", PANEL)) < 0)
		return -1;
    Radio_ConvertFromTree (panelHandle, PANEL_RADIOGROUP);
	DisplayPanel (panelHandle);
	
	CreateUDPChannel (UDP_ANY_LOCAL_PORT, & UDPWriteHandle);  //打开UDP端口
	GetUDPAttribute (UDPWriteHandle, ATTR_UDP_PORT, & localPort);
    SetCtrlVal(panelHandle,PANEL_LOCALPORT,localPort);
	SetCtrlVal(panelHandle,PANEL_MULTICASTSTRING,MULTICAST_ADDRESS); //显示多点传播地址
	SetCtrlVal(panelHandle,PANEL_BROADCASTSTRING,UDP_LAN_BROADCAST_ADDR); //显示广播发送地址
	
	RunUserInterface ();
	//释放UDP资源
	if(UDPWriteHandle)
	{
	   DisposeUDPChannel (UDPWriteHandle);
	}
	DiscardPanel (panelHandle);
	return 0;
}

int CVICALLBACK SendData (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{   
	unsigned int stringLen;   //待发送字符串长度
	char * sendString;		  //待发送字符串
	unsigned int destinationPort;  //远程端口
	unsigned int radioVal;
	char address[16];      //假定输入IP地址无误(可以通过设置属性“最大可输入长度”来保证)。					 
	
	switch (event)
	{
		case EVENT_COMMIT:
			 GetCtrlAttribute (panelHandle, PANEL_TEXTBOX, ATTR_STRING_TEXT_LENGTH, & stringLen);
			 stringLen++;   //长度包括null
			 sendString=(char *)malloc(stringLen*sizeof(char));
			 GetCtrlVal(panelHandle,PANEL_TEXTBOX,sendString);		 //读取待发送的字符串
			 GetCtrlVal(panelHandle,PANEL_DESTINATIONPORT,& destinationPort); //读取远程端口值
			 
			 GetCtrlVal(panelHandle,PANEL_RADIOGROUP,&radioVal);	//读取发送方式
			 switch(radioVal)
			 {
			     case 0:	 //unicast
					 GetCtrlVal(panelHandle,PANEL_UNICASTSTRING,address);
					 break;
			     case 1:	 //multicast
					 GetCtrlVal(panelHandle,PANEL_MULTICASTSTRING,address);
					 break;
			     case 2:	 //broadcast
					 strcpy (address, UDP_LAN_BROADCAST_ADDR);
					 break;   
			 }
			 
			 UDPWrite (UDPWriteHandle, destinationPort, address, sendString, stringLen);  //向远程端口发送数据	 
			 
			 free(sendString);
			break;
	}
	return 0;
}
//关闭面板
int CVICALLBACK panelCB (int panel, int event, void *callbackData,
		int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_CLOSE:
			QuitUserInterface(0);
			break;
	}
	return 0;
}

 

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值