V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
linghutf

写了一个 TCP 文件传输,才发现 reactor 不是那么简单

  •  
  •   linghutf · May 9, 2016 · 4103 views
    This topic created in 3653 days ago, the information mentioned may be changed or developed.
    • 思路是首先客户端向服务器传输文件信息的序列化信息,像文件名,大小, MD5 校验码这些
    • 然后等到服务器反序列化无误并发送确认信息后,客户端再发送文件内容
    • 服务器收到文件内容,对数据校验比对,如果不对就发送信息重传
    • 开始的时候是用 golang 写的,基本全是同步阻塞方式收发数据。写的过程中觉得这种效率不高,然后就想到了自己最近研究的 libevent
    • 一个小小的 scp 命令扩展居然也涉及到了序列化,异步回调,多线程,以及自己在想办法使用 zero-copy 的技术。确实出乎自己的意料
    • 对 libevent 的理解也更深了,之前的相互等待 BUG 调试让我印象很深。
    • 发上来是希望有经验的网络开发者,以后可以交流一下。
    • 地址:file-tcp
    15 replies    2016-05-12 16:07:17 +08:00
    gamexg
        1
    gamexg  
       May 9, 2016 via Android
    >socket 阻塞式读写,应该改成 IO 事件通知方式,有优化空间

    这个是什么意思? golang 不是会对外是同步阻塞,内部根据系统内部自动的使用最优的方案吗?
    binux
        2
    binux  
       May 9, 2016
    是你自己没想清楚状态转移,已经出错状态转移吧。
    bengol
        3
    bengol  
       May 10, 2016 via Android
    这是你自己的问题
    linghutf
        4
    linghutf  
    OP
       May 10, 2016
    @binux
    @bengol 确实没想清楚,对 golang 的封装的 TCP 不了解,还是使用普通 socket 的方式去思考的。
    mengzhuo
        5
    mengzhuo  
       May 10, 2016 via iPhone
    科科,楼主还是好好看书和标准库代码吧
    一个 io.Copy 搞定了
    tcp 保证数据完整和顺序
    go 本身的协程 调度器 保证不阻塞
    net 模块保障 zerocopy
    linghutf
        6
    linghutf  
    OP
       May 10, 2016
    @mengzhuo go 代码用的就是 io.Copy 啊,虽然 TCP 保证可靠,你能不做检验吗?
    linghutf
        7
    linghutf  
    OP
       May 10, 2016
    我发现在这个社区不能分享东西,都是些你自己怎么怎么样,去看书,难道谁天生就会很多? @livid 请求删除这个主题吧
    mengzhuo
        8
    mengzhuo  
       May 10, 2016 via iPhone
    @linghutf
    以太包有校验
    tcp 包有校验

    go 本身对于底层做得非常精巧,你偏偏要秀 libevent ?为什么这么快?就是因为这两用的都是系统的多路复用,你不知道罢了。
    go 的 zero copy 也是依赖系统的 sendfile , sendfile 又是依赖主板上的 dma 。

    正因为没人天生会,所以叫你多看书,多学学
    这怎么了?玻璃心的话那没治。

    下载器有校验是因为文件是多线程分块传输的
    scp 不算狠 rsync 都是计算文件块的 sum 值来达到变更数据更新的

    当然,欢迎 pr 、建议、指正
    linghutf
        9
    linghutf  
    OP
       May 10, 2016
    @mengzhuo 就知道回复就会有人说玻璃心,呵呵,删帖吧
    wadahana
        10
    wadahana  
       May 10, 2016
    觉得 lz 的需求可以 写个脚本跑 netcat 实现。。
    linghutf
        11
    linghutf  
    OP
       May 10, 2016
    实际项目中不校验?那直接 conn.Read()得到文件名,如果有 io.Copy ,对方 conn.Write()之后 io.Copy 不就完成一个 TCP 文件传输。
    但我只是学习使用这些工具,序列化,数据校验, reactor 模式,异步 IO 不行吗?
    我知道什么事情都想怎么简单怎么来,但是我作为一个初级的开发者,还是一个在校的学生,这样简单做能找到工作吗?
    这就叫社区充满一股戾气,自以为看问题很犀利,却总是忽视别人的需求。
    fcicq
        12
    fcicq  
       May 10, 2016
    @linghutf 大致总结起来就是你需要遵守术业有专攻的规则.
    首先没有人期望你的实现能够服务于多少人. 即便如此, 方案的成熟程度也和期望使用频率大致成正比.
    如上所说 golang 有 io.Copy, nodejs stream 的 pipe() 方法都是异常方便的. 这是语言和库提供的福利, 不需要自己去考虑 sendfile 或者 splice 等等的问题.
    一个透过现代 TLS 加密和 POST 上传请求可以解决的问题, 不需要楼主增添无谓的序列化和校验复杂度, 其中还暴露了楼主没有密码学基础的事实. 只有楼主一个用户的情况下快和不快重要吗? 不同的框架支持不同的异步模式, 使用了某语言就需要接受语言的思维, 并固定的使用这种语言所提供的工具组合, 框架大致也是同理.
    mengzhuo
        13
    mengzhuo  
       May 11, 2016 via iPhone   ❤️ 1
    @linghutf 直说你要用尽量多的技术来找工作不就好了。照你这样直接被刷的。做技术最怕就是一知半解装逼说名词,就算混进去了,迟早要露馅的。

    戾气?你只看我说的玻璃心三个字,读了上下文了么?
    我跟你解释了原理、源码结构、更好的参考还叫戾气?
    知道 rtfm 么?那才叫戾气。
    mengzhuo
        14
    mengzhuo  
       May 11, 2016 via iPhone
    最后再扯一句,用的东西简单,不代表你不用学里面的内部实现
    大巧不工、重剑无锋
    工作之后你就明白了
    firefox12
        15
    firefox12  
       May 12, 2016 via iPad
    阻塞写法 没什么性能差的,绝对的速度影响在磁盘 io 上面。你的网络速度是完全可以超过磁盘速度的。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   850 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 20:32 · PVG 04:32 · LAX 13:32 · JFK 16:32
    ♥ Do have faith in what you're doing.