【JokerのZYNQ7020】UDP_ECHO_LINUX。

软件环境:vivado 2017.4        硬件平台:XC7Z020


工程与前一篇linux下操作axi_uartlite用的是同一个工程,所以网口自然用的是PS端的网口,主要是想要说明zynq平台linux下怎样通过网口收发udp的数据。

由于用的是PS端的网口,所以设备树中PS部分没有什么需要修改的地方,默认生成的就行。也没啥额外需要注意的,直接撸代码。

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
		
int main(int argc, char **argv)
{
	int n = 0;   
	char recvline[1500] = {0};
	int sockfd;
	int peer_len = sizeof(struct sockaddr_in);
	
	struct sockaddr_in server_addr;	
	struct sockaddr_in client_addr;
	
	/* 创建一个UDP连接的socket */
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	/*server_addr初始化*/
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);	
	server_addr.sin_port = htons(9000);
	
	bzero(&client_addr, sizeof(client_addr));
	
	/* 绑定server_addr初始化到创建的socketfd上 */
	bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));		
	
	while(1)
	{		
		/*接收数据并通过client_addr获取源相关信息*/
		n = recvfrom(sockfd, recvline, sizeof(recvline), 0, (struct sockaddr *)&client_addr, &peer_len);
		/*将接收到的数据发回给源*/
		sendto(sockfd, recvline, n, 0, (struct sockaddr *)&client_addr, peer_len);
		
		memset(recvline, 0, sizeof(recvline)); 
	}	

	/* 关闭socket连接 */
	close(sockfd);
	
	return 0;
}

首先需要先创建两个与socket有关的sockaddr_in结构体,用于绑定本地socket信息和接收源socket信息。

struct sockaddr_in
{
	sa_family_t			sin_family;		//地址族
	uint16_t			sin_port;		//16位TCP/UDP端口号
	struct	in_addr		sin_addr;		//32位IP地址
	char				sin_zero[8];	//不使用
}

然后使用socket(AF_INET, SOCK_DGRAM, 0);来获取socket句柄,并利用server_addr初始化本地socket相关信息,INADDR_ANY绑定本机所有IP地址,监听本机所有IP地址上的9000端口。

利用bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));将初始化的句柄和本地socket信息绑定在一起。

接下来进入主函数了,主要也就是利用recvfrom()接收信息,利用sendto()发送信息,这里需要注意,默认情况下,recvfrom()是阻塞模式,也就是说,程序会一直卡在recvfrom()这里,直到接收到数据才向下执行。

ssize_t recvfrom(int sock, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

//sock:索引将要从其接收数据的套接字
//buf:存放消息接收后的缓冲区
//len:buf所指缓冲区的容量
//flags:操作标志,不同标志完成不同动作
//from:指向存放发送方地址的区域,如果为NULL,不储存发送方地址
//fromlen:作为输入参数,指向存放表示from最大容量的内存单元。作为输出参数,指向存放from实际长度的内存单元
ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

//sock:索引将要从其发送数据的套接字
//buf:指向将要发送数据的缓冲区
//len:buf所指缓冲区的容量
//flags:操作标志,不同标志完成不同动作
//to:指向存放接收方地址的区域,可以为NULL
//tolen:以上内存区的长度,可以为0

发送的函数出了sendto之外,还有send可以用,跟sendto差不多。

ssize_t send(int sock, const void *buf, size_t len, int flags);

这里主要还是贴直接就能使用的代码,至于socket建立的整个原理呀,flag参数详细的意义呀,等等等等,一方面可以百度,另一方面,实际试试,操作下就知道各个参数都有什么影响了。

代码达到的效果就是,发送给板子什么UDP信息,板子就回给PC什么UDP信息。类似于echo msg。

放心吧~贴上来的代码,都是实测过的~!没问题的~ 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值