服务端向客户端传输文件
时间:2022-07-23
本文章向大家介绍服务端向客户端传输文件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
23.1 阅读须知
本篇为:客户端向服务端请求文件传输,服务端根客户端需求发送文本文件(就是能用写字板打开成我们能看懂的文件,可能有些我没测到)
所以如果不符合你的需求就不用往下了。
23.2 代码及注释
//这是用socket传输文件的服务端
#include<netinet/in.h> // sockaddr_in
#include<sys/types.h> // socket
#include<sys/socket.h> // socket
#include<stdio.h> // printf
#include<stdlib.h> // exit
#include<string.h> // bzero
#define SERVER_PORT 8000
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main(void)
{
// 声明并初始化一个服务器端的socket地址结构
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
// 创建socket,若成功,返回socket描述符
int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);
if(server_socket_fd < 0)
{
perror("Create Socket Failed:");
exit(1);
}
int opt = 1;
setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// 绑定socket和socket地址结构
if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))
{
perror("Server Bind Failed:");
exit(1);
}
// socket监听
if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))
{
perror("Server Listen Failed:");
exit(1);
}
while(1)
{
// 定义客户端的socket地址结构
struct sockaddr_in client_addr;
socklen_t client_addr_length = sizeof(client_addr);
// 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信
// accept函数会把连接到的客户端信息写到client_addr中
int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);
if(new_server_socket_fd < 0)
{
perror("Server Accept Failed:");
break;
}
// recv函数接收数据到缓冲区buffer中
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
{
perror("Server Recieve Data Failed:");
break;
}
// 然后从buffer(缓冲区)拷贝到file_name中
char file_name[FILE_NAME_MAX_SIZE+1];
bzero(file_name, FILE_NAME_MAX_SIZE+1);
strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));
printf("%sn", file_name);
// 打开文件并读取文件数据
FILE *fp = fopen(file_name, "r");
if(NULL == fp)
{
printf("File:%s Not Foundn", file_name);
}
else
{
bzero(buffer, BUFFER_SIZE);
int length = 0;
// 每读取一段数据,便将其发送给客户端,循环直到文件读完为止
while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
{
if(send(new_server_socket_fd, buffer, length, 0) < 0)
{
printf("Send File:%s Failed./n", file_name);
break;
}
bzero(buffer, BUFFER_SIZE);
}
// 关闭文件
fclose(fp);
printf("File:%s Transfer Successful!n", file_name);
}
// 关闭与客户端的连接
close(new_server_socket_fd);
}
// 关闭监听用的socket
close(server_socket_fd);
return 0;
}
//这是用socket传输文件的客户端栗子
#include<netinet/in.h> // sockaddr_in
#include<sys/types.h> // socket
#include<sys/socket.h> // socket
#include<stdio.h> // printf
#include<stdlib.h> // exit
#include<string.h> // bzero
#define SERVER_PORT 8000
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main()
{
// 声明并初始化一个客户端的socket地址结构
struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(INADDR_ANY);
client_addr.sin_port = htons(0);
// 创建socket,若成功,返回socket描述符
int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(client_socket_fd < 0)
{
perror("Create Socket Failed:");
exit(1);
}
// 绑定客户端的socket和客户端的socket地址结构 非必需
if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))
{
perror("Client Bind Failed:");
exit(1);
}
// 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0)
{
perror("Server IP Address Error:");
exit(1);
}
server_addr.sin_port = htons(SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
// 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接
if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)
{
perror("Can Not Connect To Server IP:");
exit(0);
}
// 输入文件名 并放到缓冲区buffer中等待发送
char file_name[FILE_NAME_MAX_SIZE+1];
bzero(file_name, FILE_NAME_MAX_SIZE+1);
printf("Please Input File Name On Server:t");
scanf("%s", file_name);
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));
// 向服务器发送buffer中的数据
if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)
{
perror("Send File Name Failed:");
exit(1);
}
// 打开文件,准备写入
FILE *fp = fopen(file_name, "w");
if(NULL == fp)
{
printf("File:t%s Can Not Open To Writen", file_name);
exit(1);
}
// 从服务器接收数据到buffer中
// 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止
bzero(buffer, BUFFER_SIZE);
int length = 0;
while((length = recv(client_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)
{
if(fwrite(buffer, sizeof(char), length, fp) < length)
{
printf("File:t%s Write Failedn", file_name);
break;
}
bzero(buffer, BUFFER_SIZE);
}
// 接收成功后,关闭文件,关闭socket
printf("Receive File:t%s From Server IP Successful!n", file_name);
close(fp);
close(client_socket_fd);
return 0;
}
23.3 测试情况
1、先运行服务器代码,然后再运行客户端。没有服务器客户端准备连哪里去? 2、发送可执行文件的话是无法运行的,可以把代码传过去然后自己再编译一遍,这个是允许的。 3、如果接收到的文件出现异常,先检查服务器里面的文件,可能那个文件本来就不正常呀,不是传输的问题。 4、目前测试过有txt, C,C++,H等文件
- Golang语言捕获panic异常并转化为error
- 在Windows下安装TensorFlow
- JavaFX——(第一篇:介绍篇)
- 自编码器是什么?有什么用?这里有一份入门指南(附代码)
- UWP基础教程 - {x:DeferLoadStrategy}
- UWP基础教程 - 重启应用
- html5打开摄像头
- UWP基础教程 - App多语言支持
- Golang实现Fibonacii的几种算法
- 【译】使用 dotnet watch 开发 ASP.NET Core 应用
- vmware安装ubuntu12.04嵌套安装xen server(实现嵌套虚拟化)
- Golang语言切片slice的线程协程安全问题
- ASP.NET Core 在 Azure 开启 HTTPS
- 算法基础:最大递减数问题(Golang实现)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 将终结点图添加到你的ASP.NET Core应用程序中
- Stata | 爬取 CFPS 文献传送门并制作成 Markdown
- 委托的好处
- Elasticsearch安装和配置
- Notes | QUAIDS 模型
- Stata | 520,听说你也想快点找到...
- Stata | 批量替换变量值的小技巧
- 手把手教你完成课设作业使用Pandas对海平面温度异常进行分析,小白也能看的懂
- 谈谈自学 Stata 的体会
- Latex修改字体字号的大小
- Notes | GitHub Upload Large Files
- PPT 中插入图片的几个小技巧
- Stata | 整理调查问卷修改内容清单
- LaTeX | 绘制微观经济学图形
- Python | 地址数据清理相关的库