Go语言 之TCP文件传输
服务端实现流程大致如下:
- 创建监听listener,程序结束时关闭。
- 阻塞等待客户端连接,程序结束时关闭conn。
- 读取客户端发送文件名。保存fileName。
- 回发“ok”给客户端做应答
- 封装函数 RecvFile接收客户端发送的文件内容。传参fileName 和conn
- 按文件名Create文件,结束时Close
- 循环Read客户端发送的文件内容,当读到EOF说明文件读取完毕。
- 将读到的内容原封不动Write到创建的文件中
package main import (
"fmt"
"net"
"os"
"runtime"
) func Handler(conn net.Conn) {
buf := make([]byte, 2048)
//读取客户端发送的内容
n, err := conn.Read(buf)
if err != nil {
fmt.Println(err)
return
}
fileName := string(buf[:n])
//获取客户端ip+port
addr := conn.RemoteAddr().String()
fmt.Println(addr + ": 客户端传输的文件名为--" + fileName)
//告诉客户端已经接收到文件名
conn.Write([]byte("ok"))
//创建文件
f, err := os.Create(fileName)
if err != nil {
fmt.Println(err)
return
}
//循环接收客户端传递的文件内容
for {
buf := make([]byte, 2048)
n, _ := conn.Read(buf)
//结束协程
if string(buf[:n]) == "finish" {
fmt.Println(addr + ": 协程结束")
runtime.Goexit()
}
f.Write(buf[:n])
}
defer conn.Close()
defer f.Close()
} func main() {
//创建tcp监听
listen, err := net.Listen("tcp", ":8000")
if err != nil {
fmt.Println(err)
return
}
defer listen.Close() for {
//阻塞等待客户端
conn, err := listen.Accept()
if err != nil {
fmt.Println(err)
return
}
//创建协程
go Handler(conn)
}
}
客户端实现流程大致如下:
- 提示用户输入文件名。接收文件名path(含访问路径)
- 使用os.Stat()获取文件属性,得到纯文件名(去除访问路径)
- 主动连接服务器,结束时关闭连接
- 给接收端(服务器)发送文件名conn.Write()
- 读取接收端回发的确认数据conn.Read()
- 判断是否为“ok”。如果是,封装函数SendFile() 发送文件内容。传参path和conn
- 只读Open文件, 结束时Close文件
- 循环读文件,读到EOF终止文件读取
- 将读到的内容原封不动Write给接收端(服务器)
package main import (
"fmt"
"io"
"net"
"os"
) //发送文件到服务端
func SendFile(filePath string, fileSize int64, conn net.Conn) {
f, err := os.Open(filePath)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
var count int64
for {
buf := make([]byte, 2048)
//读取文件内容
n, err := f.Read(buf)
if err != nil && io.EOF == err {
fmt.Println("文件传输完成")
//告诉服务端结束文件接收
conn.Write([]byte("finish"))
return
}
//发送给服务端
conn.Write(buf[:n]) count += int64(n)
sendPercent := float64(count) / float64(fileSize) * 100
value := fmt.Sprintf("%.2f", sendPercent)
//打印上传进度
fmt.Println("文件上传:" + value + "%")
}
} func main() {
fmt.Print("请输入文件的完整路径:")
//创建切片,用于存储输入的路径
var str string
fmt.Scan(&str)
//获取文件信息
fileInfo, err := os.Stat(str)
if err != nil {
fmt.Println(err)
return
}
//创建客户端连接
conn, err := net.Dial("tcp", ":8000")
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
//文件名称
fileName := fileInfo.Name()
//文件大小
fileSize := fileInfo.Size()
//发送文件名称到服务端
conn.Write([]byte(fileName))
buf := make([]byte, 2048)
//读取服务端内容
n, err := conn.Read(buf)
if err != nil {
fmt.Println(err)
return
}
revData := string(buf[:n])
if revData == "ok" {
//发送文件数据
SendFile(str, fileSize, conn)
}
}
Go语言 之TCP文件传输的更多相关文章
- 艺萌TCP文件传输及自动更新系统介绍(TCP文件传输)(四)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开源,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)
艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...
- qt+boost::asio+tcp文件传输
客户端: void qt_boost::pbSendFileClicked(){ QString filename = ui.leFileName->text(); QByteArray ba ...
- Java 简单TCP文件传输
服务端 package TCP; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputSt ...
- python基础实现tcp文件传输
准备工作,实现文件上传需要那些工具呢? socket(传输).open()(打开文件).os(读取文件信息),当然还有辅助类sys和json,下面我们开始吧 import socket,sys imp ...
- Java Tcp文件传输---转载
/** 客户端 1.服务端点 2.读取客户端已有的文件数据 3.通过socket输出流发给服务端 4.读取服务端反馈信息 5.关闭 **/ import java.io.*; import java. ...
- 在TCP文件传输中如何判断java流的末尾
感谢前辈们的解答:https://bbs.csdn.net/topics/280085530 问题描述: 服务端向客户端发送数据流,服务端发完了数据不关闭流. 我在客户端读流,我无法读到-1,所以无法 ...
- Linux网络编程:socket文件传输范例
基于TCP流协议的socket网络文件传输Demo: 实现:C语言功能:文件传输(可以传任何格式的文件) /********************************************** ...
- Windows网络编程:winsock文件传输范例
基于TCP流协议的winsock网络文件传输Demo: 实现:C语言 功能:文件传输(可以传任何格式的文件) /******************************************** ...
随机推荐
- CentOS7/RHEL6下,如何查看目录与子目录大小
原文:CentOS7/RHEL6下,如何查看目录与子目录大小 通过强大的[du]命令,可以帮助我们快捷的查看目录的大小,非常实用. du命令用来查看目录或文件所占用磁盘空间的大小.常用选项组合为:du ...
- JS数组操作,赋值指向同一指针
1.使用slice() 可使用slice()进行复制,因为slice()返回也是数组. var array1 = new Array("1","2"," ...
- Python 基础问题大全
前言 Python现在依托大数据,AI人工智能等等这些最火的项目,俨然已经成为了当下最火的一门编程语言之一. 所以,近来也是有非常非常多的工程师来进修python这么语言. 但是实际上,对于0代码基础 ...
- stm32 RS485 SP3485
RS485 是半双工通信(2 线制) SP3485芯片的DE与RE短接在一起连接在STM32F1芯片的PG3上,通过PG3管脚就可以控制 SP3485的收发,当PG3=0时,为接收模式,当PG3=1时 ...
- Ubuntu 文件和目录常用命令
目标 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 > 和 &g ...
- C C++输出格式 <转载>仅用于个人
转载链接:C++ C C语言输出格式总结 1 一般格式 printf(格式控制,输出表列) 例如:printf("i=%d,ch=%c\n",i,ch); 说明: ...
- 三星Q470c Logo界面无限掉电重启,变砖后的挽救过程
背景 三星笔记本的部分型号如:NP530 Q470等 安装win8后再次重装系统(我弄了个Ubuntu18)会导致无法进入BIOS菜单页面的问题.启动显示logo页面后,能够听到明显啪的一声(硬盘掉电 ...
- Maven打包Web项目成war包——4
1. 需要安装maven 的war插件支持 在pom.xml里面配置war插件 2. 运行命令: mvn clean package 3.部署到Tomcat下面发布,并访问!
- java中的io流总结(二)——RandomAccessFile类
知识点:RandomAccessFile (随机访问文件)类 (一)描述 前一篇博客中https://www.cnblogs.com/shuaifing/p/11490160.html,主要描述Fil ...
- 【万能的DFS和BFS基础框架】-多刷题才是硬道理!