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语言 功能:文件传输(可以传任何格式的文件) /******************************************** ...
随机推荐
- vue-cli中eslint配置
在项目目录下找到.eslintrc.js文件,使用编辑器打开进行编辑.在rules下添加space-before-function-paren.space-before-blocks.及semi的配置 ...
- 【原创】大叔经验分享(86)hive和mysql数据互导
hive和mysql数据互导,首先想到的是sqoop,并且可以和调度框架(比如oozie等)配合配置定时任务,还有一种更简单的方式是通过spark-sql: CREATE OR REPLACE TEM ...
- Linux 命令行:cURL 的十种常见用法
Linux 命令行:cURL 的十种常见用法 文章目录 1. 获取页面内容 2. 显示 HTTP 头 3. 将链接保存到文件 4. 同时下载多个文件 5. 使用 -L 跟随链接重定向 6. 使用 -A ...
- Jmeter测试出现端口占用情况
Jmeter测试会出现端口占用情况 这边在这里做个记录,每次都要百度查询,刚好需要整理下,我就也记录一份到这里吧.感谢大佬的文章. 参考文章:windows下Jmeter压测端口占用问题 因Windo ...
- Mysql 更新时间
Mysql时间加减函数为date_add().date_sub() 定义和用法DATE_ADD() 函数向日期添加指定的时间间隔.DATE_SUB() 函数向日期减少指定的时间间隔.语法DATE_AD ...
- Zookeeper 安装及集群配置注意点
Zookeeper在ubuntu下安装及集群搭建,关于集群搭建,网上很多文章 可以参考:https://www.ibm.com/developerworks/cn/opensource/os-cn-z ...
- 使用私有api实现自己的iphone桌面,并根据app的使用次数对app排序
使用<iphone SprintBoard部分私有API总结>中提到的api,除了能对app运行次数进行监控以外,还可以实现自己的iphone桌面,并根据app 的使用次数对app图标进行 ...
- 9.Redis的Java客户端Jedis
Redis的Java客户端Jedis Jedis所需jar包 commons-pool-1.6.jar jedis-2.1.0.jar 1.Jedis常用操作(jedis中的api 和 我们在 l ...
- [LeetCode] 24. Swap Nodes in Pairs ☆☆☆(链表,相邻两节点交换)
Swap Nodes in Pairs 描述 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表. 示例: 给定 1->2->3->4, 你应该返回 2->1->4 ...
- 雨后清风U盘启动盘的五大用处及制作方法
如果有一个U盘可以帮助你安装系统,或者在你的电脑系统崩溃时帮助你修复系统,是不是很方便呢?雨后清风U盘启动盘就能帮你实现这样的效果.除此之外,雨后清风U盘启动盘还有另外一些用处.下面就来和大家分享一下 ...