xiexiaoy / iTalk

Just record something here
0 stars 0 forks source link

网络编程 #14

Open xiexiaoy opened 7 years ago

xiexiaoy commented 7 years ago

libuv、libev、libevent用哪个?

https://stackoverflow.com/questions/9433864/whats-the-difference-between-libev-and-libevent

libuv 初窥

xiexiaoy commented 7 years ago

网络模型把传输层从应用层里面分出来是富有智慧的决定,否则,可靠传输和拥塞控制机制与业务层逻辑搅和在一起,画面太美!

xiexiaoy commented 7 years ago

成功的补集不是失败,而是“千秋功过,留与后人评说”。就像发送方收到了确认,代表发送成功,收不到确认不代表不成功。

xiexiaoy commented 7 years ago

多进程/多线程listen的两种模式

1)主进程/线程listen,将connect请求accept下来,复制给其他进程/线程 2)每个进程/线程是平等的,他们都listen在同一port(对于多进程需要listen后fork)。tornado和nginx都是这种方式。

Is there a way for multiple processes to share a listening socket?

xiexiaoy commented 7 years ago
       sendfile()  copies  data between one file descriptor and another.  Because this copying is done within the kernel, sendfile() is more efficient than the combina‐
       tion of read(2) and write(2), which would require transferring data to and from user space.
xiexiaoy commented 7 years ago

setsockopt可以设置多个网络层次的选项 man 7 socket; man 7 tcp; man 7 ip。

ERRNO也可以返回多个层次的错误,man如上

xiexiaoy commented 7 years ago

Redis作者关于事件库的讨论

Linux epoll is now supported

Why is an Event Library needed at all?

Redis为什么不使用Libevent或者Libev

xiexiaoy commented 7 years ago

send用边缘触发 recv用水平触发

这样才是最合适的,系统可惜不提供poll。

xiexiaoy commented 7 years ago

很多close(2)虽然名字叫做关闭,其实行为是release,释放/归还资源。 同样地,open(2)也不是打开,它的行为是acquire,申请/获得资源。

xiexiaoy commented 7 years ago

one loop per process,先fork后epoll_create还是先epoll_create后fork?

先fork后epoll_create是对的,后者会共享同一个内核中的epoll数据结构。

Tornado

        if num_processes > 1 and ioloop.IOLoop.initialized():
            logging.error("Cannot run in multiple processes: IOLoop instance "
                          "has already been initialized. You cannot call "
                          "IOLoop.instance() before calling start()")
            num_processes = 1
        if num_processes > 1:
            logging.info("Pre-forking %d server processes", num_processes)
            for i in range(num_processes):
                if os.fork() == 0:
                    self.io_loop = ioloop.IOLoop.instance()
                    self.io_loop.add_handler(
                        self._socket.fileno(), self._handle_events,
                        ioloop.IOLoop.READ)
                    return
            os.waitpid(-1, 0)

Re: Fw: epoll and fork()

xiexiaoy commented 7 years ago

leveldb和protobuf的变长编码varint似乎是相同的。

xiexiaoy commented 7 years ago

协议的可扩展性:TCP的头部的Options字段,每个选项的长度为32bit,最多可以包括10个选项,即40Byte。 TCP头部的长度字段只表示了头部的长度,没有哪个字段是表示尾部的长度的,因此TCP是一个流协议。

xiexiaoy commented 7 years ago

MSS TCP最大分节大小,MTU减去IP报头和TCP报头 MSL TCP分节的最大生存时间 TTL IP数据报的最大跳数 RTT 往返时延

xiexiaoy commented 7 years ago

TCP中,窗口是以段(segment,MSS)为单位的,一个MSS通常为1460Bytes,cwnd就是x*MSS

xiexiaoy commented 7 years ago

ACK数据报不消耗序列号,但是SYN和FIN消耗序列号。

xiexiaoy commented 7 years ago

TIME_WAIT状态

  1. 有序关闭。比如对FIN的ACK丢失了,对方重传FIN,需要确认。
  2. 耗尽离群的段。防止出现在新的连接中。
xiexiaoy commented 7 years ago

一个进程能够使用的TCP连接数是有限的,而且多线程公用一个TCP连接时有隔离性问题。 解决方法就是复用一条TCP连接——Channle

xiexiaoy commented 7 years ago

5 subtle ways you're using MySQL as a queue, and why it'll bite you

不要用数据库做消息队列。

xiexiaoy commented 7 years ago

IP分片。

实现IP分片需要三个成员:

  1. IP的ID,被分片的数据包享有共同的ID。
  2. 未结束的标志,如果标志为1,则有后续的分段,否则,标志位0的分段就是最后的分段。
  3. 偏移,对乱序到达的分段进行重组。

IP数据包的最大长度为65535,是一个与链路层无关的值,目的是使IP协议与数据链路层MTU无关。这样,当新发明另一种链路层协议,IP协议依然适用。IP位于沙漏腰部。

IP分组的校验和只校验头部,是因为上层协议对数据做校验,而且数据部分在路由器中保持不变,头部内容却可能变化。

xiexiaoy commented 7 years ago

所谓IO复用,复用的不是IO,复用的是线程

xiexiaoy commented 6 years ago

时至今日,还有许多网络模块不支持连接复用!比如数据库连接,并发的查询完全可以走同一条连接嘛!