OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4991|回复: 2

嵌入式iTOP-4412开发板实现基于UDP的socket编程

[复制链接]

45

主题

57

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
250
金钱
250
注册时间
2015-5-7
在线时间
10 小时
发表于 2016-3-10 18:06:56 | 显示全部楼层 |阅读模式
1金钱

平台:iTOP-4412开发板
本文讲解一下基于 UDP socket 编程, UDP是用户数据报协议,它是一种无连接的传输层协议,提供面向事物的简单不可靠信息传送服务,所以在一些网络质量不满意的环境下,UDP 协议数据包丢失会比较严重,会造成数据的丢失。UDP 的特点是他不属于连接型协议,所以资源消耗小。处理速度快的优点,所以通常音频,视频和普通数据在传送时使用 UDP 较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
UDP 的通信框图如下图所示:
图片1.jpg
从上图可以看到基于 UDP 通信的程序也是由服务器和客户端组成。与 TCP 的服务器不同,UDP 的服务器不
需要 listen accept 函数,客户端不需要 connect 函数。
下面我们通过一个例子来了解一下 UDP 的应用程序,首先我们来看下服务器(server)端的程序 server.c
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char **argv)
{
int n;
char recvline[1024] = {0};
int sockfd;
struct sockaddr_in servaddr;
/* 创建一个 UDP 连接的 socket */
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
/* 变量 servaddr 清零 */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(50001);
/* 绑定 servaddr 到创建的 socket */
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
/* 接收客户端发送的数据 */
recvfrom(sockfd, recvline, 1024, 0, NULL, NULL);
printf("%s\n", recvline);
/* 关闭 socket 连接 */
close(sockfd);
}
上面的代码和我们前面一章的 TCP 的服务器程序差不多,首先也是定义一些变量,然后调用 socket 函数创建
一个套接字,这里 socket 函数的第二个参数是 SOCK_DGRAM,即用户数据报,也就是创建的 UDP 连接,
然后调用 bzero 函数清空变量 servaddr 的值,然后设置 servaddr 结构的值,接着调用 bind 绑定函数,然
后调用 recvfrom 函数直接接收数据,而没有调用 listen accept 函数。
下面我们来看看客户端(client)的程序 client.c:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
{
printf("usgae: ./client [ip]\n");
return -1;
}
/* 创建一个 UDP socket 连接 */
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
/* 变量 servaddr 清零 */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(50001);
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
char sendline[100];
sprintf(sendline, "Hello, world!");
/* 发送数据 */
sendto(sockfd, sendline, strlen(sendline), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
/* 关闭 socket 连接 */
close(sockfd);
return 1;
}
客户端(client)的程序首先是定义一些使用的变量,然后也是调用 socket 函数创建一个套接字,socket
数的第二个参数是 SOCK_DGRAM,即用户数据报,也就是 UDP 连接,然后调用 bzero 函数把 servaddr
构的变量清零, 然后设置 servaddr 结构变量的值, 然后调用 sendto 发送函数, 这里客户端程序没有调用 bind
函数和 connect 函数。现在我们使用命令
gcc -o server server.c
执行结果如下图:
图片2.jpg
使用命令 arm-none-linux-gnueabi-gcc -o client client.c 编译 client.c,执行结果如下图:
图片3.jpg
我们把生成的 client 拷贝到我们的 NFS 文件系统的 bin 目录下,如下图:
图片4.jpg
然后我们在虚拟机 Ubuntu 上运行 server 程序,如下图:
图片5.jpg
4412 开发板上运行 client 程序,如下图:
图片6.jpg
执行结果如下图:
图片7.jpg
现在我们看下虚拟机 Ubuntu server 程序的输出,如下图:
图片8.jpg
我们可以看到 server 程序输出“Helloword” ,上面的打印信息就是 client 发送的数据。至此基于 UDP socket 通讯就实现了。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

16

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
332
金钱
332
注册时间
2015-12-3
在线时间
54 小时
发表于 2016-3-10 18:45:00 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165353
金钱
165353
注册时间
2010-12-1
在线时间
2108 小时
发表于 2016-3-12 00:02:17 | 显示全部楼层
谢谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 22:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表