golang文件传输服务
2014-03-07 22:27
477 查看
续上篇,本篇介绍一个完整的golang文件传输服务器。
完整的代码可以看服务器,客户端
网络使用的框架如上篇介绍,这里就不再复述.
首先定义3个命令码:
request_file用于请求文件传输,附带的命令参数是文件key.
file_size用于通告客户端文件的大小.
transfering用于传输文件内容,附带参数是文件内容的二进制数据.
服务器的文件配置示例
上面的文件配置了3个文件可供传输=左边是文件路径,右边是请求文件时使用的key.
服务器启动时首先调用loadfile将文件导入到内存中,然后根据定义的key,将文件内容插入到字典filemap中:
接着是服务其的packet_handler:
如果收到的消息是requestfile,首先查看请求的文件是否存在,如果存在则创建一个文件传输过程transfersession,
并将它与tcpsession绑定,然后发出一个文件大小通告包,紧接着立即调用send_file开始发送文件内容.
sendfile中根据当前发送位置判断还有多少内容需要发送,如果剩余内容小于16000字节就将所剩数据一次性
发出,否则 发送16000字节的数据,并调整发送位置。注意到Send函数带了一个sendfinish函数作为参数,其作用
是当数据包发送 完成后回调send_finish函数.
send_finish的作用是判断文件是否已经发送完,如果发完断开连接,否则接着发送剩余部分.
总结一下,golang用来编写服务器应用还是相当方便的,很多细节问题在语言层面或系统库里已经帮你解决掉了
,可以将主要的 精力放在逻辑的处理上.
完整的代码可以看服务器,客户端
网络使用的框架如上篇介绍,这里就不再复述.
首先定义3个命令码:
const ( request_file = 1 file_size = 2 transfering = 3 )
request_file用于请求文件传输,附带的命令参数是文件key.
file_size用于通告客户端文件的大小.
transfering用于传输文件内容,附带参数是文件内容的二进制数据.
服务器的文件配置示例
../learnyouhaskell.pdf=haskell ../golang.1.1.2.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) > 1 { line = line[0:len(line)-1]//drop '\n' fileconfig := strings.Split(line,"=") if len(fileconfig) == 2 { buf, err := ioutil.ReadFile(fileconfig[0]) if err != nil { fmt.Printf("%s load error\n",fileconfig[0]) }else{ filemap[fileconfig[1]] = buf fmt.Printf("%s load success,key %s\n",fileconfig[0],fileconfig[1]) } } } } 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:0} session.SetUd(tsession) wpk := packet.NewWpacket(packet.NewByteBuffer(64),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 := 0 if remain >= 16000 { sendsize = 16000 }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用来编写服务器应用还是相当方便的,很多细节问题在语言层面或系统库里已经帮你解决掉了
,可以将主要的 精力放在逻辑的处理上.
相关文章推荐
- python起的 simpleHTTPServer服务传输文件
- 基于RMI服务传输大文件的完整解决方案
- Linux---FTP文件传输服务
- Linux中的ftp文件传输服务
- CentOS 7.0 使用Vsftpd服务传输文件
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2
- xshell使用xftp传输文件、使用pure-ftpd搭建ftp服务
- xshell使用xftp传输文件,pure-ftpd搭建ftp服务
- 15.4 xshell使用xftp传输文件;15.5 使用pure-ftpd搭建ftp服务
- FTP文件服务搭建与同步传输
- golang 远程传输文件
- uucico命令_Linux uucico 命令用法详解:Linux uucico命令UUCP文件传输服务程序。 uucico是用来处理uucp或uux送到队列的文件传输工具。uucico有两种工作模式:主动模式和附属模式。当在主动模式下时,uucico会调用远端主机;在附属模式下时,uucico则接受远端主机的调用。
- 使用GoLang实现文件远程传输
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室]
- 15.4 xshell使用xftp传输文件 15.5 使用pure-ftpd搭建ftp服务
- 第11章 使用Vsftpd服务传输文件
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室]
- xshell使用xftp传输文件、使用pure-ftpd搭建ftp服务
- 详解“FTP文件传输服务”安装配置实例 推荐
- FTP文件服务搭建与同步传输