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

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

一、简述

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

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

       例子是一个简单的测试,还有很多细节没有考虑,还有待完善!

二、效果

在Ubuntu16.04上测试,recv接收文件,send发送文件。(注意测试环境不同可能结果不同,多数是因为程序逻辑问题)

      

三、源文件 

       recv.c文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>


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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libgen.h>//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通。

        

         

 

五、接收文件内容为空

      请在send.c 的以下内容添加以下延时

      感谢qq_****2863指出!!!   (是在Ubuntu 12.04.2 LTS 32bit上遇到的)

 

Linux 中使用代码实现简单TCP 文件传输客户端可以使用 C 语言和 Socket 编程来完成。以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #define PORT 8080 #define BUFF_SIZE 1024 int main() { int sock = 0, valread; struct sockaddr_in serv_addr; char buffer[BUFF_SIZE] = {0}; FILE *file; // 创建客户端的 socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将 IP 地址从字符串转换为二进制形式 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { perror("inet_pton failed"); exit(EXIT_FAILURE); } // 连接服务器端的 socket if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("connect failed"); exit(EXIT_FAILURE); } // 发送文件名给服务器端 char *filename = "example.txt"; send(sock, filename, strlen(filename), 0); // 创建新文件以保存接收到的数据 file = fopen("received_file.txt", "wb"); if (file == NULL) { perror("File creation failed"); exit(EXIT_FAILURE); } // 接收并写入文件内容 memset(buffer, 0, sizeof(buffer)); while ((valread = read(sock, buffer, BUFF_SIZE)) > 0) { fwrite(buffer, 1, valread, file); memset(buffer, 0, sizeof(buffer)); } // 关闭连接和文件 close(sock); fclose(file); return 0; } ``` 这个例子演示了一个简单TCP 文件传输客户端的实现。它创建一个客户端的 socket,并连接到指定的服务器 IP 地址和端口。然后,它发送文件名给服务器端,并创建一个新文件用于保存接收到的数据。接下来,它接收服务器端发送的文件内容,并将内容写入文件中。 请注意,这只是一个简单的示例代码,没有进行错误处理和完整性检查。在实际应用中,你可能需要添加额外的逻辑来处理错误、检查文件是否存在、处理断点续传等功能。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值