TA的每日心情 | 难过 2021-2-27 22:16 |
---|
签到天数: 1568 天 连续签到: 1 天 [LV.Master]伴坛终老
|
实现的功能:
完成一个UDP服务器端程序,实现接收客户端的报文,在串口终端打印出来,同时将报文返回给客户端。
1 硬件连接
EVB-335X-II 只引出了一路以太网,使用 RMII 协议的信号,在底板上使用 LAN8720A 实现物理层的连接。10/100Mbps 自适应网络,集成 RJ45 网络变压器,网络变压器接口引脚定义见图:
2 UDP介绍
UDP(User Datagram Protocol) 用户数据报协议,是一个面向无连接的协议。采用该协议不需要两个应用程序先建立连接。UDP协议不提供差错恢复,不能提供数据重传,因此该协议传输数据安全性差。UDP 与 TCP 的主要区别在于 UDP 不一定提供可靠的数据传输。事实上,该协议不能保证数据准确无误地到达目的地。UDP 在许多方面非常有效。当某个程序的目标是尽快地传输尽可能多的信息时(其中任意给定数据的重要性相对较低),可使用 UDP。
3 UDP编程
UDP编程的服务器端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();
4、循环接收数据,用函数recvfrom();
5、关闭网络连接;
UDP编程的客户端一般步骤是:
1、创建一个socket,用函数socket();
2、设置socket属性,用函数setsockopt();* 可选
3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
4、设置对方的IP地址和端口等属性;
5、发送数据,用函数sendto();
6、关闭网络连接;
4 程序分析
方便排版,这里只介绍部分代码 :
#define SERVER_PORT 8888
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT);
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("bind error!\n");
return -1;
}
while (1)
{
iAddrLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
sendto(iSocketServer, ucRecvBuf, strlen(ucRecvBuf), 0, (struct sockaddr *)&tSocketClientAddr, sizeof(struct sockaddr_in));
}
close(iSocketServer);
5 应用程序编译与测试
编译:
arm-linux-gnueabihf-gcc -o serverD server.c ,如下截图:
测试:
终端运行可执行程序,截图:
开发板收到客户端的报文后,将报文打印出来。
上位机截图:
上位机发送报文 “Hello Bbs.elecfans! ” 。同时接受到 开发板 发送回来的报文。显示出来 。
到此,UDP服务器端应用程序测试成功。
|
|