Linux-C 简单的TCP文件传输例子

Linux-C 简单的TCP文件传输例子

一、简述

       记--使用TCP协议进行端到端的文件传输 的简单例子。并利用该程序将Ubuntu将文件传输到开发板。

       例子打包:链接: https://pan.baidu.com/s/1q88GZLWTQ-yQqkLAsQ9r_Q 提取码: spms 

二、效果

recv接收文件,send发送文件。

      Linux-C 简单的TCP文件传输例子_第1张图片

三、源文件 

       recv.c文件

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


int main(int argc, char *argv[])
{
	//判断命令行参数是否匹配
	if(argc != 2)
	{
		printf("./recv port\n");
		return -1;
	}
	
	//创建tcp通信socket
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		perror("create socketfd failed\n");
		return -1;
	}
	
	
	//绑定地址
	struct sockaddr_in local_addr = {0};
	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(atoi(argv[1])); 
	local_addr.sin_addr.s_addr = INADDR_ANY;//让系统自动检测本地网卡IP并绑定
	int ret = bind(tcp_socket, (struct sockaddr *)&local_addr, sizeof(local_addr));
	if (ret == -1)
	{
		perror("bind  failed\n");
		return -1;
	}
	
	
	//设置监听队列
	ret = listen(tcp_socket, 5);
	if(ret == -1)
	{
		perror("listen is fail\n");
		return -1;
	}
	
	
	//客户端地址信息
	struct sockaddr_in client_addr={0};
	int len = sizeof(client_addr);
		 
	printf("server is running\n");
	
	//通信socket
	int new_socket = 0;
	
	while (1)
	{
		//等待客户端的请求
		new_socket = accept(tcp_socket,(struct sockaddr *)&client_addr,&len);
		if(new_socket < 0)
		{
			perror("accept error\n");
			continue;
		}
		
		//输出对方的IP地址信息
		printf("client connected [%s:%d]\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
				
		char file_len[16] = {0};//文件长度
		char file_name[128] = {0};//文件名称
		char buf[1024] = {0};//数据缓冲区
		//读取文件大小和文件名称
		read(new_socket, buf, sizeof(buf));
		
		strncpy(file_len, buf, sizeof(file_len));//取出文件大小
		strncpy(file_name, buf+sizeof(file_len), sizeof(file_name));//取出文件名称
		
		printf("ready receive!!!! file name:[%s] file size:[%s] \n",file_name, file_len);
		
		//新的文件名
		sprintf(buf, "recv-%s", file_name);
		
		//创建新文件
		int fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666);
		
		int size = atoi(file_len);//文件大小
		int write_len = 0;//记录已写入的字节数
		
		//接收文件
		while(1)
		{
			bzero(buf, 1024);
			
			//接收文件数据
			ret = read(new_socket, buf, sizeof(buf));
			if( ret <= 0)
			{
				printf("\n [recv-%s] receive file done!!!\n", file_name);
				break;
			}
			
			//将数据写入文件	
			write(fd, buf, ret);
			
			write_len += ret;//记录写入的字节数

			//动态的输出接收进度
			printf("uploading %.2f%% \n", (float)write_len/size * 100);
			
		}
		
		break;
		
	}
	
	//关闭socket
	close(new_socket);
	close(tcp_socket);
	
	return 0;
}

send.c文件

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include //basename():从路径中获取文件名及后缀


int main(int argc, char * argv[])
{
	if(argc != 3)
	{
		printf("请输入文件接收方的IP、端口号\n");
		return -1;
	}
	
	int port = atoi(argv[2]);
	
	//创建TCP通信socket
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		perror("create socketfd is fail\n");
		return -1;
	}
	
	
	
	//目的地址
	struct sockaddr_in dest_addr = {0};
	dest_addr.sin_family = AF_INET;
	dest_addr.sin_port = htons(port); 	
	dest_addr.sin_addr.s_addr = inet_addr(argv[1]);
	
	int ret = -1;
	//请求连接目标地址

	ret = connect(tcp_socket, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
	if(ret != 0)//连接成功
	{
		perror("connect failed\n");
		return -1;
	}
	
	printf("\nConnect succeed!\n");
	
	char file_path[128] = {0};//文件路径
	char file_info[2048] = {0};//文件信息
	
	
	char buf[1024] = {0};
	
	//获取用户输入的文件路径
	printf("Please enter file path: ");
	scanf("%s", file_path);
	
	//从文件路径中获取文件名,如"test/a.txt" ==> "a.txt"
	char file_name[128] = {0};
	strncpy(file_name, basename(file_path), sizeof(file_name));
	
	//打开文件
	int fd = open(file_path, O_RDWR);
	if (fd == -1)
	{
		printf("open [%s]  failed", file_path);
		return -1;
	}	
	
	//计算文件大小
	int len = lseek(fd, 0, SEEK_END);

	//文件光标偏移到文件开始位置
	lseek(fd, 0, SEEK_SET);
	
	
	//将文件大小和文件名存放到file_info
	sprintf(file_info, "%d", len);
	strcpy(file_info + 16, file_name);
		
	
	// 将需要上传的文件名告诉对方 
	write(tcp_socket, file_info, 144);	

	int send_len = 0;//记录发送了多少字节
	
	while (1)
	{	
		bzero(buf, sizeof(buf));
		//读取数据
		ret = read(fd, buf, sizeof(buf));
		if (ret <= 0)
		{
			printf("send file[%s] succeed!!!!\n", file_name);
			break;
		}
			
		//发送数据
		write(tcp_socket, buf, ret);
		
		send_len += ret;//统计发送了多少字节
		
		//上传文件的百分比 
		printf("uploading %.2f%%\n", (float)send_len/len * 100);
	}
	
	// 关闭文件 
	close(fd);
	//关闭通信socket 
	close(tcp_socket);
	return 0;
}

四、Ubuntu传输文件到开发板

       注:Ubuntu与开发板互相ping通。

        Linux-C 简单的TCP文件传输例子_第2张图片

         Linux-C 简单的TCP文件传输例子_第3张图片

你可能感兴趣的:(Linux)