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

概述

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

首先来看看实现的效果。

1. 实现一次传输

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

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

首先在云服务器端运行server

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

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

  • 客户端:

  • 服务端

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

2. 程序流程

  • 客户端

  • 服务端

3. 文件传输源代码

1. 客户端client.c

#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

#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. 实现一次传输2. 程序流程3. 文件传输源代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部