golang文件传输服务

时间:2022-01-10 23:57:06

续上篇,本篇介绍一个完整的golang文件传输服务器。

完整的代码可以看服务器,客户端

网络使用的框架如上篇介绍,这里就不再复述.

首先定义3个命令码:

const (
request_file =
file_size =
transfering =
)

request_file用于请求文件传输,附带的命令参数是文件key.

file_size用于通告客户端文件的大小.

transfering用于传输文件内容,附带参数是文件内容的二进制数据.

服务器的文件配置示例

../learnyouhaskell.pdf=haskell
../golang.1.1..chm=golang
../NodeJS.pdf=NodeJS

上面的文件配置了3个文件可供传输=左边是文件路径,右边是请求文件时使用的key.

服务器启动时首先调用loadfile将文件导入到内存中,然后根据定义的key,将文件内容插入到字典filemap中:

func loadfile(){
//从配置导入文件
F,err := os.Open("./config.txt")
if err != nil {
fmt.Printf("config.txt open failed\n")
return
}
filemap = make(map[string][]byte)
bufferReader := bufio.NewReader(F)
eof := false
for !eof {
line,err := bufferReader.ReadString('\n')
if err == io.EOF{
err = nil
eof = true
}else if err != nil{
fmt.Printf("parse file error\n")
return
}
if len(line) > {
line = line[:len(line)-]//drop '\n'
fileconfig := strings.Split(line,"=")
if len(fileconfig) == {
buf, err := ioutil.ReadFile(fileconfig[])
if err != nil {
fmt.Printf("%s load error\n",fileconfig[])
}else{
filemap[fileconfig[]] = buf
fmt.Printf("%s load success,key %s\n",fileconfig[],fileconfig[])
}
}
}
} if filemap["golang"] == nil {
fmt.Printf("golang not found\n")
} fmt.Printf("loadfile finish\n")
}

接着是服务其的packet_handler:

func process_client(session *tcpsession.Tcpsession,rpk *packet.Rpacket){
cmd,_ := rpk.Uint16()
if cmd == request_file {
if session.Ud() != nil {
fmt.Printf("already in transfer session\n")
}else
{
filename,_ := rpk.String()
filecontent := filemap[filename]
if filecontent == nil {
fmt.Printf("%s not found\n",filename)
session.Close()
}else{
fmt.Printf("request file %s\n",filename)
tsession := &transfer_session{filecontent:filecontent,ridx:}
session.SetUd(tsession) wpk := packet.NewWpacket(packet.NewByteBuffer(),false)
wpk.PutUint16(file_size)
wpk.PutUint32(uint32(len(filecontent)))
session.Send(wpk,nil)
tsession.send_file(session)
}
}
}else{
fmt.Printf("cmd error,%d\n",cmd)
session.Close()
}
}

如果收到的消息是requestfile,首先查看请求的文件是否存在,如果存在则创建一个文件传输过程transfersession,

并将它与tcpsession绑定,然后发出一个文件大小通告包,紧接着立即调用send_file开始发送文件内容.

func (this *transfer_session)send_file(session *tcpsession.Tcpsession){
remain := len(this.filecontent) - this.ridx
sendsize :=
if remain >= {
sendsize =
}else{
sendsize = remain
}
wpk := packet.NewWpacket(packet.NewByteBuffer(uint32(sendsize)),false)
wpk.PutUint16(transfering)
wpk.PutBinary(this.filecontent[this.ridx:this.ridx+sendsize])
session.Send(wpk,send_finish)
this.ridx += sendsize
}

sendfile中根据当前发送位置判断还有多少内容需要发送,如果剩余内容小于16000字节就将所剩数据一次性

发出,否则 发送16000字节的数据,并调整发送位置。注意到Send函数带了一个sendfinish函数作为参数,其作用

是当数据包发送 完成后回调send_finish函数.

func send_finish (s interface{},wpk *packet.Wpacket){
session := s.(*tcpsession.Tcpsession)
tsession := session.Ud().(*transfer_session)
if tsession.check_finish(){
session.Close()
return
}
tsession.send_file(session)
}

send_finish的作用是判断文件是否已经发送完,如果发完断开连接,否则接着发送剩余部分.

总结一下,golang用来编写服务器应用还是相当方便的,很多细节问题在语言层面或系统库里已经帮你解决掉了

,可以将主要的 精力放在逻辑的处理上.

golang文件传输服务的更多相关文章

  1. WCF大文件传输服务

    由于项目需要,自己写一个基于WCF的大文件传输服务雏形.觉得有一定的参考价值,因此放在网上分享. 目前版本为v1.1特点如下: 1.文件传输端口为18650 2.上传和下载文件 3.支持获取文件传输状 ...

  2. 网站优化与Cdn文件传输服务

    网站优化与Cdn文件传输服务 如今互联网无处不在,其方便快捷.性质和低成本的经济特点,已经逐渐成为商务贸易.信息分发和数据交付的一个重要渠道.要想让数据的分发带来巨大的效益,那么网民的满意是唯一的办法 ...

  3. FTP文件传输服务

    FTP文件传输服务 一 .FTP 连接及传输的模式 l  控制连接:TCP21,用于发送FTP命令信息. l  数据连接:TCP 20, 用于上传下载数据. · 数据连接建立的类型: ·主动模式: 服 ...

  4. Python自带HTTP文件传输服务

    一行命令搭建一个基于python的http文件传输服务 由于今天朋友想要一个文件,而我恰好有,因为这个文件比较大,网速不是很给力,所以想到了python自己有这么一个功能,这样不仅不需要下载其他软件, ...

  5. FTP 文件传输服务

    昨晚心血来潮,尝试用python写了一个ftp文件传输服务,可以接收指令,从远程ftp服务器同步指定目录数据,最后没用上,开源出来. https://github.com/jadepeng/ftp_t ...

  6. 基于WCF的支持跨局域网可断点续传的大文件传输服务实现

    题外话:这个系列的文章记录了本人最近写的一个小工程,主要包含了两个功能,一是对文件的断点续传的功能,二是基于WCF的一对多文件主动发送的功能,顺便这也是我自己在WCF学习路上的一个小成果吧. 在网上找 ...

  7. 基于UDT connect连接通信以及文件传输--服务端

    网上与UDT相关的资料不多,与UDT相关的源码例子更少.最近在接触UDT,也是因为缺少相关的资料,导致学习起来甚感痛苦.下面将我自己这两天弄出来的代码贴出来,希望对在寻找相关资料的童鞋有一定的帮助.与 ...

  8. golang 文件传输小demo(转载)

    转载地址:https://www.cnblogs.com/qq702368956/p/10195497.html 获取文件信息需要用到os. Stat接口,发送文件前开启接收者(服务端),启动客户端先 ...

  9. FTP文件传输服务!

    一.FTP  连接及传输模式 1.控制连接:TCP 21,用于发送 FTP 命令信息2.数据连接:TCP 20,用于上传.下载数据3.数据连接的建立类型: (1)主动模式:服务器主动发起数据连接 (2 ...

随机推荐

  1. WPFMediaKit照相功能

    最近写的一个WPF照相功能,往各位吐槽,提供优化 在WPF 设计器中添加如下代码 xmlns:wpfmedia="clr-namespace:WPFMediaKit.DirectShow.C ...

  2. P107、面试题15:链表中倒数第K个结点

    题目:输入一个链表,输出该链表中倒数第K个结点.为了符合大多数人的习惯,本体从1开始奇数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点,从头结点开始他们的值一次是1.2.3.4.5.6.这个 ...

  3. ZOJ 2412 Farm Irrigation(DFS 条件通讯块)

    意甲冠军  两个农田管内可直接连接到壳体  他们将能够共享一个水源   有11种农田  管道的位置高于一定  一个农田矩阵  问至少须要多少水源 DFS的连通块问题  两个相邻农田的管道能够直接连接的 ...

  4. smarty模板做人员表信息删除,修改 里面的性别单选按钮民族下拉,另外登录进去可以显示姓名

    首先登录进去可以显示姓名 smarty模板做人员表信息删除,删除的时候有提示框确定删除吗. 修改 里面的性别单选按钮,要修改谁有默认选中,用了变量调节器 民族位置做下拉,用<{foreach}& ...

  5. &lbrack;乐意黎原创&rsqb; cuteftp 9 显示中文乱码

    当用FTP连接空间时.中文命名的文件名称会显示乱码,原来是编码设置错误.怎么改动呢? 改动方法例如以下: 选择. 工具--> 全局选项->传输: 1. 传输方法: ASCII 2. SFT ...

  6. phpmyadmin nginx设置

    1,解压缩phpmyadmin4.2.8压缩包到/usr/local/phpMyAdmin 2,复制config.sample.inc.php为config.inc.php 3,修改nginx.con ...

  7. python第四十三天--第三模块考核

    面向对象: 概念:类,实例化,对象,实例 属性: 公有属性:在类中定义 成员属性:在方法中定义 私有属性:在方法中使用 __属性  定义 限制外部访问 方法: 普通方法 类方法: @classmeth ...

  8. Eclipse复制或修改项目后,把项目部署后发现还是原来的项目名称

    Eclipse复制或修改项目后,把项目部署后发现还是原来的项目名称 解决: 到项目根目录打开.setting文件夹,找到"org.eclipse.wst.common.component&q ...

  9. SpringData&lowbar;CrudRepository接口

    CrudRepository CrudRepository 接口提供了最基本的对实体类的添删改查操作 T save(T entity);//保存单个实体 Iterable<T> save( ...

  10. 【JSON&period;parse&lpar;&rpar;和JSON&period;stringify&lpar;&rpar;】

    var str = '{"name":"huangxiaojian","age":"23"}' 结果: JSON.par ...