int udp_sendmsg() { // corkreq 为 true 表示是 MSG_MORE 的方式,仅仅组织报文,不发送; int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; // 将要发送的数据,按照MTU大小分割,每个片段一个skb;并且这些 // skb会放入到套接字的发送缓冲区中;该函数只是组织数据包,并不执行发送动作。 err...
还是线程安全的,不用lock_sock(sk)加锁,单纯是因为没必要。 开启MSG_MORE时多个线程会同时写到同一个socket_fd对应的发送缓冲区中,然后再统一一起发送到IP层,因此需要有个锁防止出现多个线程将对方写的数据给覆盖掉的问题。而不开启MSG_MORE时,数据则会直接发送给IP层,就没有了上面的烦恼。 再看下udp的接收函...
而我们大部分情况下,都不会用 MSG_MORE,也就是来一个数据包就直接发一个数据包。从这个行为上来说,虽然 UDP 用上了发送缓冲区,但实际上并没有起到 "缓冲" 的作用。
还是线程安全的,不用lock_sock(sk)加锁,单纯是因为没必要。 开启MSG_MORE时多个线程会同时写到同一个socket_fd对应的发送缓冲区中,然后再统一一起发送到IP层,因此需要有个锁防止出现多个线程将对方写的数据给覆盖掉的问题。而不开启MSG_MORE时,数据则会直接发送给IP层,就没有了上面的烦恼。 再看下udp的接收函...
而我们大部分情况下,都不会用 MSG_MORE ,也就是来一个数据包就直接发一个数据包。从这个行为上来说,虽然UDP用上了发送缓冲区,但实际上并没有起到"缓冲"的作用。 - EOF - 点击标题可跳转 1、 深入理解 CPU 的调度原理 2、 看起来满是 bug 的排序代码,居然是对的 ...
但是,我们一般也用不到MSG_MORE。 所以我们直接关注另外一个分支,也就是不加锁直接发消息。 那是不是说明走了不加锁的分支时,udp发消息并不是线程安全的? 其实。还是线程安全的,不用lock_sock(sk)加锁,单纯是因为没必要。 开启MSG_MORE时多个线程会同时写到同一个socket_fd对应的发送缓冲区中,然后再统一一...
// 这边等待write buffer有空间 wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: if (copied) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); // 这边等待timeo长的时间 if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) goto do_er...
这就使ZMQ应用程序可以和非ZMQ程序进行交流。当使用原始模式的时候,你不能使用明确的身份ID,并且在发送消息的时候ZMQ_MSGMORE标志也会被忽略。在原始模式下,你可以采用在发送了一个明确的身份ID后,紧跟着发送一个空消息来关闭一个指定的连接。 不建议使用这个选项,请使用ZMQ_STREAM 类型的socket来代替。
eBPF 程序还可以用来拦截所有 sendmsg 系统调用,根据系统调用的参数去 map 里查找 peer socket,之后调用 BPF 函数 bpf_msg_redirect_hash() 来绕过 TCP/IP 协议栈,直接将数据发送到对端的 socket RX queue。图 6 中 _sk_msg 代表了这样的 eBPF 程序。
public boolean continueReading(UncheckedBooleanSupplier maybeMoreDataSupplier) { return config.isAutoRead() && // respectMaybeMoreData为false时表示不“慎重”对待读取更多数据,只要有数据就一直读16次,默认true // maybeMoreDataSupplier是判断有更多数据的可能性 ...