网络编程(TFTP协议实验)

这篇具有很好参考价值的文章主要介绍了网络编程(TFTP协议实验)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <head.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define PORT 69       //端口号:填服务器绑定端口号
#define IP   "192.168.1.101"   //IP地址:windows的IP地址

int upload(int cfd,struct sockaddr_in sin)
{
	char filename[20] = "";
	printf("请输入要上传的文件名>>> ");
	scanf("%s", filename);
	while(getchar()!=10);

	//判断文件存不存在
	int fd = open(filename,O_RDONLY);
	if(fd < 0)
	{
		ERR_MSG("open");
		return -1;
	}
	//发送数据
	char buf[516] = "";
	int size = sprintf(buf, "%c%c%s%c%s%c", 0, 2, filename, 0, "octet", 0);
	if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)) < 0) 
	{
		ERR_MSG("sendto");
		return -1;
	}
	printf("sendto success\n");
	socklen_t addrlen = sizeof(sin);
	ssize_t res = 0;
	unsigned short num = 0;      //本地记录的块编号

	while(1)
	{
		bzero(buf, sizeof(buf));
		//接收服务器的应答
		res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &addrlen);
		if(res < 0)
		{
			ERR_MSG("recvfrom");
			break;
		}

		if(4 == buf[1])
		{
			if(htons(num) == *(unsigned short*)(buf+2))
			{
				//组数据包给服务器
				num++;
				*(unsigned short*)buf = htons(3);
				*(unsigned short*)(buf+2) = htons(num);

				res = read(fd, buf+4, 512);
				if(res < 0)
				{
					break;
				}
				else if(0 == res)
				{
					printf("文件:%s 上传完毕\n", filename);
					break;
				}

				//发送数据包
				if(sendto(cfd, buf, res+4, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
				{
					ERR_MSG("sendto");
					return -1;
				}
			}
		}
		else if(5 == buf[1])//错误包
		{
			printf("MSG_ERR: code[%d] msg[%s] __%d__\n", \
					ntohs(*(unsigned short*)(buf+2)), buf+4, __LINE__);
			break;
		}

	}

	close(fd);
	return 0;
}

int download(int cfd,struct sockaddr_in sin)
{

	char buf[516] = "";

	char filename[20] = "";
	printf("请输入要下载的文件名>>> ");
	scanf("%s", filename);
	while(getchar()!=10);

	//发送下载请求
	//组协议包
	int size = sprintf(buf, "%c%c%s%c%s%c", 0, 1, filename, 0, "octet", 0);
	//sendto 
	if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("sendto");
		return -1;
	}

	//本地创建并打开要下载的文件
	int fd = -1;     //必须初始化一个无意义的文件描述符,否则下面的close

	socklen_t addrlen = sizeof(sin);
	ssize_t res = 0;
	unsigned short num = 0;      //本地记录的块编号

	//循环接收数据包,回复ACk
	while(1)
	{
		bzero(buf, sizeof(buf));
		//接收数据包
		res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &addrlen);
		if(res < 0)
		{
			ERR_MSG("recvfrom");
			break;
		}

		if(3 == buf[1])     //数据包
		{
			if(htons(num+1) == *(unsigned short*)(buf+2))
			{
				num++;

				if(-1 == fd)
				{
					fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664);
					if(fd < 0)
					{
						ERR_MSG("open");
						break;
					}
				}

				//将获取到的数据,写入到文件中
				if(write(fd, buf+4, res-4) < 0)
				{
					ERR_MSG("write");
					break;
				}

				buf[1] = 4;
				if(sendto(cfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
				{
					ERR_MSG("sendto");
					break;
				}

				if(res-4 < 512)
				{
					printf("======= 文件下载完毕 =======\n");
					break;
				}
			}
		}
		else if(5 == buf[1])//错误包
		{
			printf("MSG_ERR: code[%d] msg[%s] __%d__\n", \
					ntohs(*(unsigned short*)(buf+2)), buf+4, __LINE__);
			break;
		}

	}
	close(fd);
	return 0;
}
int main(int argc, const char *argv[])
{
	//创建报式套接字
	int cfd = socket(AF_INET,SOCK_DGRAM,0);
	if(cfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("cfd = %d\n",cfd);

	//绑定客户端的地址信息结构体到套接字上--->非必须绑定
	//若不绑定,则操作系统会给客户端绑定上客户端所在的主机IP以及随机端口(49151~65535)

	//填充地址信息结构体,真实的地址信息结构体根据地址族制定
	//AF_INET:man 7 ip
	//要连接哪个服务器,就填对应服务器的IP和端口
	struct sockaddr_in sin;
	sin.sin_family      = AF_INET;       //必须填AF_INET
	sin.sin_port        = htons(PORT);   //端口号:填服务器绑定端口号
	sin.sin_addr.s_addr = inet_addr(IP);  //IP地址:服务器绑定的IP地址

	char c = 0;

	while(1)
	{	
		printf("-------------------------\n");
		printf("---------1.下载----------\n");
		printf("---------2.上传----------\n");
		printf("-------------------------\n");
		printf("请输入>>> ");
		c = getchar();
		while(getchar()!=10);
		switch(c)
		{
		case '1' :
			download(cfd,sin);
			break;
		case '2' :
			upload(cfd,sin);
			break;
		default :
			printf("输入错误,请重新输入\n");
			break;
		}
		while(getchar()!=10);

	}

	//关闭所有文件描述符
	close(cfd);

	return 0;
}

网络编程(TFTP协议实验),网络文章来源地址https://www.toymoban.com/news/detail-646121.html

到了这里,关于网络编程(TFTP协议实验)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [C++ 网络协议编程] UDP协议

    目录 1. UDP和TCP的区别 2. UDP的工作原理 3. UDP存在数据边界 4. UDP的I/O函数 4.1 sendto函数 4.2 recvfrom函数 4. 已连接(connected)UDP套接字和未连接(unconnected)UDP套接字 5. UDP的通信流程 5.1 服务器端通信流程 5.2 客户端通信流程 主要区别: TCP和UDP的主要区别是,TCP具有流控制机制,而UDP没

    2024年02月12日
    浏览(44)
  • [C++ 网络协议编程] 域名及网络地址

    DNS(Domain Name System):是对IP地址和域名(如:www.baidu.com等)进行相互转换的系统,其核心是DNS服务器。 我们输入的www.baidu.com是域名,是一种虚拟地址,而非实际地址,DNS服务器会将这个虚拟地址转换为实际地址,即IP地址。若我们直接输入IP地址,则不会发生上面的转换。

    2024年02月12日
    浏览(41)
  • 【Linux网络编程】HTTP协议

    喜欢的点赞,收藏,关注一下把! 目前基本socket写完,一般服务器设计原则和方式(多进程、多线程、线程池)+常见的各种场景,自定义协议+序列化和反序列化都已经学过了。 那有没有人已经针对常见场景,早就已经写好了常见的协议软件,供我们使用呢? 当然了,最典型的

    2024年04月16日
    浏览(57)
  • 【Linux网络编程】HTTPS协议

    喜欢的点赞,收藏,关注一下把! HTTPS 是什么 HTTPS 也是一个应用层协议,是在 HTTP 协议的基础上引入了⼀个加密层。 HTTP 协议内容不管是GET还是POST都是按照文本的方式 明文传输 的,这就信息导致在传输过程中出现泄漏和被篡改的情况。所以在http和传输层直接添加一层软件

    2024年04月15日
    浏览(54)
  • 网络应用编程 实验3 矩阵并行计算练习实验

    编写一个 WPF 应用程序,利用 数据并行 计算两个矩阵(M×N和N×P)的乘积,得到一个M×P的矩阵。   具体要求 (1)在代码中用 多任务 通过 调用某方法 实现 矩阵并行 运算,在调用的参数中分别 传递M、N、P 的大小。 (2)程序中 至少要测试3次 有代表性的不同大小的矩阵运

    2024年02月05日
    浏览(37)
  • 【网络编程】一文详解http协议(超文本传输协议)

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。    目录 一、http协议 1、http协议的介绍 2、URL的组成 3、urlencode和urldecode 二、http的请求方法、状态码及状态码描述、常见的响

    2024年02月06日
    浏览(71)
  • 【Java】--网络编程:基于TCP协议的网络通信

    TCP协议(Transmission Control Protocol),即传输控制协议,是一种 面向连接 的, 可靠 的,基于 字节流 的传输层通信协议。数据大小无限制。 建立连接的过程需要 三次握手 。 断开连接的过程需要 四次挥手 。 使用TCP协议的通信双方分别为 客户端 和 服务器端 。 客户端负责向服务

    2024年01月23日
    浏览(61)
  • 【网络编程】网络通信基础——简述TCP/IP协议

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 ip地址简单来说就是用来描述网络上一个设备的所在位置。 端

    2024年02月04日
    浏览(62)
  • linux【网络编程】之HTTP协议

    在上篇文章中我们模拟了一个应用层协议,HTTP(超文本传输协议)就是其中之一。http就是通过http协议从服务器上读取对应的“资源”,这里所说的资源是在网络上看到的一切都可以看成资源文件;访问资源就是根据路径,从服务器磁盘上拿取资源 平时我们俗称的 “网址” 其

    2024年02月07日
    浏览(49)
  • 【Linux网络编程】HTTPS协议原理

    HTTPS也是⼀个应⽤层协议,是在HTTP协议的基础上引⼊了⼀个加密层,HTTP协议内容都是按照⽂本的⽅式明⽂传输的,这就导致在传输过程中出现⼀些被篡改的情况。 加密就是把 明文 (要传输的信息)经过一系列的变换,变成 密文 进行传输。 解密就是把 密文 在通过一系列的

    2024年02月07日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包