前面我们学习了TCP Socket以及TCP数据的采集与存储。现在我们来看下UDP Socket以及UDP数据的采集。
UDP协议在IP协议之上运行。UDP协议用于哪些无可靠性、响应、传输层流控制要求的应用。它很简单,仅需要将UDP端口以及是否选择校验和提供给传输层。
UDP协议是一简单的字节流服务。它不知道发送数据的格式,只是简单地接受数据,将其压缩成包并发送给远程对等体。
UDP协议不需要等待任何的响应,也不能检测到任何丢失的包。当需要响应或检测时,必须在应用层完成。然而,当需要响应时最好使用TCP Socket。
#include <RTL.h>
#include <stdio.h>
#include <LM3Sxxxx.H>
#include <string.h>
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
// <h>Remote IP Address
// ====================
//
// <o>IP1: Address byte 1 <0-255>
// <i> Default: 192
#define IP1 192
// <o>IP2: Address byte 2 <0-255>
// <i> Default: 168
#define IP2 168
// <o>IP3: Address byte 3 <0-255>
// <i> Default: 0
#define IP3 14
// <o>IP4: Address byte 4 <0-255>
// <i> Default: 100
#define IP4 8
// </h>
// <o>Remote Port <1-65535>
// <i> Do not set number of port too small,
// <i> maybe it is already used.
// <i> Default: 1001
#define PORT_NUM 1001
// <o>Communication Protocol <0=> TCP <1=> UDP
// <i> Selecet a protocol for sending data.
#define PROTOCOL 1
// <o>LED Blinking speed <1-100>
// <i> Blinking speed = SPEED * 100ms
// <i> Default: 2
#define SPEED 2
//------------- <<< end of configuration section >>> -----------------------
#define UDP 1
BOOL tick;
U8 socket_udp;
U8 Rem_IP[4] = {IP1,IP2,IP3,IP4};
/*--------------------------- init ------------------------------------------*/
static void init () {
/* Add System initialisation code here */
/* Set the clocking to run from the PLL at 50 MHz */
SysCtlClockSet (SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
/* Configure the GPIO for the LED. */
SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOF);
GPIOPadConfigSet (GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_STRENGTH_2MA,
GPIO_PIN_TYPE_STD);
GPIODirModeSet (GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_DIR_MODE_OUT);
/* Setup and enable the SysTick timer for 100ms. */
SysTickPeriodSet(SysCtlClockGet() / 10);
SysTickEnable();
}
/*--------------------------- timer_poll ------------------------------------*/
static void timer_poll () {
/* System tick timer running in poll mode */
if ((HWREG (NVIC_ST_CTRL) >> 16) & 1) {
/* Timer tick every 100 ms */
timer_tick ();
tick = __TRUE;
}
}
/*--------------------------- UDP socket ------------------------------------*/
U16 udp_callback (U8 soc, U8 *rip, U16 rport, U8 *buf, U16 len) {
buf = buf;
rip = rip;
rport= rport;
len = len;
soc = soc;
return (0);
}
void send_data (U8 p2val) {
U8 *sendbuf;
static U16 p2=0;
/* UDP */
if (socket_udp != 0) {
sendbuf = udp_get_buf (10);
p2++;
if(p2==10000)
p2=0;
sprintf((char*)sendbuf,"%d \r\n",p2);
udp_send (socket_udp, Rem_IP, 1001, sendbuf, strlen((char*)sendbuf)+1);
}
}
/*--------------------------- main ------------------------------------------*/
int main (void) {
U8 p2val, cnt, lshf;
init ();
init_TcpNet ();
socket_udp = udp_get_socket (0, UDP_OPT_SEND_CS | UDP_OPT_CHK_CS, udp_callback);
if (socket_udp != 0) {
udp_open (socket_udp, PORT_NUM);
}
p2val = 1;
cnt = 0;
lshf = 1; /* left shift */
while (1) {
timer_poll ();
main_TcpNet ();
if (tick == __TRUE) {
if (++cnt == SPEED) {
send_data(p2val);
p2val = lshf ? (p2val << 1) : (p2val >> 1);
if (p2val == 0x80) lshf = 0;
if (p2val == 0x01) lshf = 1;
cnt = 0;
}
tick = __FALSE;
}
}
}
四 UDP数据接收(PC机)
用VC6.0编写
#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
void main()
{
WORD wVersionRequested;
WSADATA wsaDataS;
int err,len;
int sockSrvS;
char recvBuf[100];//和服务器端进行通信(send/recv)
int Recv_Len;
struct sockaddr_in addrSrvS,addrClient;
wVersionRequested = MAKEWORD( 1, 1 );
while(1)
{
//服务器
err = WSAStartup( wVersionRequested, &wsaDataS );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaDataS.wVersion ) != 1 ||
HIBYTE( wsaDataS.wVersion ) != 1 ) {
WSACleanup( );
return;
}
sockSrvS=socket(AF_INET,SOCK_DGRAM,0);
addrSrvS.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrvS.sin_family=AF_INET;
addrSrvS.sin_port=htons(1001);
bind(sockSrvS,(SOCKADDR*)&addrSrvS,sizeof(SOCKADDR));
//接收
len=sizeof(SOCKADDR);
Recv_Len = recvfrom(sockSrvS,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
recvBuf[Recv_Len] = '\0';
printf("%s",recvBuf);
Sleep(1000); //等待一秒
closesocket(sockSrvS);
WSACleanup();
}
}
五 程序运行效果图
1.网络调试助手
图1
PC机程序运行效果图