V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
linghutf
V2EX  ›  分享发现

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

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

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

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

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

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

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

    戾气?你只看我说的玻璃心三个字,读了上下文了么?
    我跟你解释了原理、源码结构、更好的参考还叫戾气?
    知道 rtfm 么?那才叫戾气。
    mengzhuo
        14
    mengzhuo  
       2016-05-11 09:10:57 +08:00 via iPhone
    最后再扯一句,用的东西简单,不代表你不用学里面的内部实现
    大巧不工、重剑无锋
    工作之后你就明白了
    firefox12
        15
    firefox12  
       2016-05-12 16:07:17 +08:00 via iPad
    阻塞写法 没什么性能差的,绝对的速度影响在磁盘 io 上面。你的网络速度是完全可以超过磁盘速度的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   890 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:30 · PVG 04:30 · LAX 12:30 · JFK 15:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.