我是靠谱客的博主 诚心山水,这篇文章主要介绍C语言:实现Linux系统下利用TCP协议传输文件到阿里云服务器1. 实现一次传输2. 程序流程3. 文件传输源代码,现在分享给大家,希望可以做个参考。

最近学习了Linux下的TCP网络编程,想实践一下,于是写了利用TCP协议、传输文件到阿里云服务器的客户端程序服务端程序

首先来看看实现的效果。

1. 实现一次传输

虚拟机Ubuntu/桌面/TCP_File 目录下,有如下文件:

将其发送到自己的阿里云服务器的/home/www/website/目录下。

首先在云服务器端运行server

Ubuntu系统运行client,并输入相应的参数(云服务器地址、文件目录/文件名):

按下回车后,各界面上的响应:

  • 客户端:

  • 服务端

查看服务器端,文件已传输完成:

2. 程序流程

  • 客户端

  • 服务端

3. 文件传输源代码

1. 客户端client.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h> // 端口号6666 #define PORT 6666 // 定义buffer大小 #define BUF_SIZE 1024 // #define LISTEN_LENGTH 20 int main(int argc, char *argv[]) { printf("客户端启动...n"); // 简单判断用户输入的命令行参数,若不符合规范则给出提示 if (argc != 3) { // argv[0]是输入的第一个参数 printf("请输入正确的参数!n"); printf("格式: %s 服务器主机地址 目录/文件名 n", argv[0]); printf("举例: %s 47.110.144.145 XXX.txt n", argv[0]); // exit(1)表示异常退出 exit(1); } int sockfd, fp; // int fp; int recvBytes, sendBytes, readBytes; // 定义buffer unsigned char buffer[BUF_SIZE]; // 定义sockaddr_in结构体 struct sockaddr_in serv_addr; struct hostent *host; // 打开要发送的文件 // argv[2]是输入的第三个参数 // 打开文件方式为O_RDONLY只读方式 if ((fp = open(argv[2], O_RDONLY)) == -1) { printf("打开%s文件失败!n", argv[2]); exit(1); } printf("打开%s文件成功!n", argv[2]); // 解析hostname // argv[1]是输入的第二个参数 if ((host = gethostbyname(argv[1])) == NULL) { printf("hostname错误!n"); exit(1); } // 创建socket流式套接字 // AF_INET允许与远程主机通信 // SOCK_STREAM代表流式套接字,采用TCP协议 // 失败返回-1 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("创建socket失败!n"); exit(1); } printf("创建socket成功!n"); // 请求连接服务器 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); serv_addr.sin_addr = *((struct in_addr *)host->h_addr); // 将sin_zero清零 bzero(&(serv_addr.sin_zero), 8); // 调用connect(),失败返回-1 if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) { printf("连接服务器失败!n"); exit(1); } printf("连接服务器成功!n"); // ------------------通信阶段------------------ // 1.发送文件名 // 将buffer清零 memset(buffer, 0, sizeof(buffer)); // argv[2]是输入的第三个参数,文件名 strcpy(buffer, argv[2]); // 调用send() send(sockfd, buffer, strlen(buffer) + 1, 0); printf("发送文件名完成!n"); // 将buffer清零 memset(buffer, 0, sizeof(buffer)); // 调用recv() recvBytes = recv(sockfd, buffer, sizeof(buffer), 0); // 2.发送数据 // 将buffer清零 memset(buffer, 0, sizeof(buffer)); printf("开始发送数据...n"); // 读文件,读取的字节数为buffer的长度 // 成功返回当前读取的字节数 // 如果返回值大于0,说明可能还没读取完毕,则继续执行一次 while ((readBytes = read(fp, buffer, BUF_SIZE)) > 0) { // 调用send(),将这次读取的数据发送 // readBytes 为这次读取的字节数 sendBytes = send(sockfd, buffer, readBytes, 0); // 如果出错,返回-1,给出提示并退出 if (sendBytes < 0) { printf("× 发送文件失败!n"); exit(1); } // 将buffer清零 memset(buffer, 0, sizeof(buffer)); } printf("√ 发送文件成功!n"); // 关闭文件 close(fp); // 关闭套接字 close(sockfd); printf("客户端退出...n"); }

2. 服务端server.c

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h> #include <string.h> #include <fcntl.h> // 端口号6666 #define PORT 6666 // 定义buffer大小 #define BUF_SIZE 1024 #define Name 100 // 定义listen中请求队列的大小 #define LISTEN_LENGTH 20 void main() { // 定义sockaddr_in结构体 struct sockaddr_in server_sockaddr, client_sockaddr; int size, recvBytes, writeBytes, fp; int sockfd, listenfd; int i = 0; unsigned char filePath[Name], filePath1[Name], filePath2[Name]; // unsigned char filePath1[Name], filePath2[Name]; // 定义buffer unsigned char buffer[BUF_SIZE]; printf("服务端启动...n"); // 创建socket流式套接字,失败返回-1 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("socket创建失败!n"); exit(1); } printf("socket创建成功!listenfd=%dn", listenfd); // 绑定地址及端口 server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_port = htons(PORT); server_sockaddr.sin_addr.s_addr = INADDR_ANY; // 将sin_zero清零 bzero(&(server_sockaddr.sin_zero), 8); // 调用bind(),失败返回-1 if ((bind(listenfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))) == -1) { printf("绑定失败!n"); exit(1); } printf("绑定成功!n"); // 监听客户端请求 // 调用listen(),失败返回-1 if (listen(listenfd, LISTEN_LENGTH) == -1) { printf("监听失败!n"); exit(1); } printf("监听连接请求...n"); // 接收连接 size = sizeof(client_sockaddr); // 调用accept(),接收请求 sockfd = accept(listenfd, (struct sockaddr *)&client_sockaddr, &size); if (sockfd == -1) { printf("连接失败!n"); exit(1); } printf("连接成功!n"); // ------------------通信阶段------------------ // 1.传输文件名 // 将buffer清零 bzero(buffer, BUF_SIZE); // 调用recv(),接受数据保存在buffer recvBytes = recv(sockfd, buffer, BUF_SIZE, 0); // 把buffer中的数据复制到filePath strcpy(filePath, buffer); // 将buffer清零 memset(buffer, 0, sizeof(buffer)); // 将反馈信息放入buffer strcpy(buffer, "文件名接收成功!n"); // 应答 send(sockfd, buffer, strlen(buffer) + 1, 0); // 2.编辑文件名编辑,去除带'/'的路径 // 判断是否输入了目录 if (strchr(filePath, '/') != NULL) { // 输入了目录,作处理,去掉'/' strcpy(filePath1, strrchr(filePath, '/')); for (i = 1; filePath1[i] != ''; i++) { filePath2[i - 1] = filePath1[i]; filePath2[i] = ''; } } else // 没有输入目录,直接赋值 strcpy(filePath2, filePath); // 3.服务端创建文件 // 创建文件,并以读写方式打开 // 0777表示所有者、组成员和其他用户都有读、写和执行权限 fp = open(filePath2, O_CREAT | O_RDWR, 0777); // 创建失败返回-1 if (fp == -1) { printf("%s文件创建失败!n", filePath2); exit(1); } printf("%s文件创建成功!n", filePath2); // 4.传输文件的数据 // 将buffer清零 bzero(buffer, BUF_SIZE); printf("开始接收数据...n"); // 调用recv(),成功时返回成功接受的字节个数 // 如果返回值大于0,则可能还没有接收完毕,继续重复执行 // 接受的数据放入buffer while (recvBytes = recv(sockfd, buffer, BUF_SIZE, 0)) { // 接收过程出现错误,给出提示 if (recvBytes < 0) { printf("接收文件失败!n"); break; } // 将接受的数据写入文件中,写的个数为接受的字节数 // 成功时返回实际写入的数据 writeBytes = write(fp, buffer, recvBytes); // 实际写入数据 < 接受的数据,则传输错误 if (writeBytes < recvBytes) { printf("传输数据失败!n"); break; } // 将buffer清零 bzero(buffer, BUF_SIZE); } printf("√ 接收文件成功!n"); // 关闭文件 close(fp); // 关闭连接套接字 close(sockfd); // 关闭监听套接字 close(listenfd); printf("服务端退出...n"); }

????????欢迎在我的博客上访问:
https://lzxjack.top/

最后

以上就是诚心山水最近收集整理的关于C语言:实现Linux系统下利用TCP协议传输文件到阿里云服务器1. 实现一次传输2. 程序流程3. 文件传输源代码的全部内容,更多相关C语言:实现Linux系统下利用TCP协议传输文件到阿里云服务器1.内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(93)

评论列表共有 0 条评论

立即
投稿
返回
顶部