【Linux】网络篇三--UDP编程



一、编程思路

在这里插入图片描述
由于是无连接传输,重点使用recvfrom函数sendto函数实现编程。


二、编程实现

1、sendto/recvfrom

ssize_t sendto(int socket, void *message, size_t length, 
int flags, struct sockaddr *dest_addr, socklen_t dest_len);

ssize_t recvfrom(int socket, void *buffer, size_t length, 
int flags, struct sockaddr *address, socklen_t *address_len);
  • socketsocket() 调用返回
  • message/address :接收/发送的信息
  • length :信息长度
  • flag :一般填0
  • struct sockaddr :存放服务器或客机的端口号与ip地址
  • address_len :地址长度

2、程序实现

sever.c:

/*************************************************************************
	> File Name: sever.c
	> Author: xiuchengzhen
	> CSDN: xiuchengzhen.blog.csdn.net
	> Created Time: Thu 31 Mar 2022 03:40:52 AM PDT
 ************************************************************************/

#include "net.h"

int main(int argc, const char *argv[])
{
	/************socket设置**************/
	int fd;
	if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket:");
		exit(-1);
	}
	/*********允许绑定地址快速重用**********/
	int b_reuse = 1;
	setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
	
	/***********bind设置****************/
	struct sockaddr_in sin;
	memset(&sin, 0, sizeof(sin));  //清零
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SER_PORT);
#if 1
	sin.sin_addr.s_addr = htonl(INADDR_ANY);  //可以接收随机的ip地址
#else
	if(inet_pton(AF_INET, SER_ADDR, (void *)&sin.sin_addr) != 1)
	{
		perror("inet_pton:");
		exit(-1);
	}
#endif
	if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
	{
		perror("bind:");
		exit(-1);
	}

	printf("Net bind success!\n");
	/*********recvfrom************/

	char buf[BUFSIZE] = {0};  //接收数据储存的地方
	char client_addr[16] = {0}; //储存客机地址的地方 
	struct sockaddr_in cin;
	socklen_t cinlen = sizeof(cin);
	while(1)
	{
		bzero(buf, sizeof(buf));
		if(recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&cin, &cinlen) < 0)
		{
			perror("recvfrom:");
			continue;
		}

		bzero(client_addr, sizeof(client_addr));
		if(inet_ntop(AF_INET, (void *)&cin.sin_addr, client_addr, sizeof(client_addr)) == NULL)
		{
			perror("inet_ntop:");
			continue;
		}

		/******打印接收信息******/
		printf("sever read:%s, client port:%d, client ip:%s\n", buf, ntohs(cin.sin_port), client_addr);

		if(strncasecmp(buf, USER_QUIT, strlen(USER_QUIT)) == 0) //接收quit退出
			printf("client port %d,client ip %s choice break!\n", ntohs(cin.sin_port), client_addr);

	}
	return 0;
}

client.c:

/*************************************************************************
	> File Name: client.c
	> Author: xiuchengzhen
	> CSDN: xiuchengzhen.blog.csdn.net
	> Created Time: Thu 31 Mar 2022 05:03:20 AM PDT
 ************************************************************************/

#include "net.h"

void in_error()  //打印错误信息与输入提示
{
	printf("Error or no arguments were entered at runtime\n");
	printf("Please input such as : ./file port ip\n");
	printf("5000< port <65525\n");
	exit(-1);
}

int main(int argc, const char *argv[])
{
	if(argc < 3)
		in_error();
	int port = atoi(argv[1]);
	if(port < 5000 || port < 0)
		in_error();

	/*********socket地址族***********/
	int fd;
	if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket:");
		exit(-1);
	}

	/*******sendto********/
	char buf[BUFSIZE] = {0};
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	if(inet_pton(AF_INET, argv[2], (void *)&sin.sin_addr) < 0)
	{
		perror("inet_pton:");
		exit(-1);
	}
	
	socklen_t addrlen = sizeof(sin);
	printf("client ready!\n");
	while(1)
	{
		if(fgets(buf, sizeof(buf), stdin) == NULL) //从键盘获取数据
		{
			perror("fgets:");
			continue;
		}

		if(sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, addrlen) < 0) //发送数据
		{
			perror("sendto:");
			continue;
		}

		if(strncasecmp(buf, USER_QUIT, strlen(USER_QUIT)) == 0)  //输入quit退出
		{
			printf("client choice break!\n");
			exit(-1);
		}
	}
	
	return 0;
}

三、实验结果

在这里插入图片描述


到这里就结束啦!
在这里插入图片描述

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修成真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值