微信网站开发哪家好市场调研报告范文模板

当前位置: 首页 > news >正文

微信网站开发哪家好,市场调研报告范文模板,嘉兴做网站设计,陕西省交通建设集团商界分公司网站文章目录 Posix API和网络协议栈#xff0c;使用TCP实现P2P通信1. socket()2. bind()3. listen()4. connect()5. accept()6. read()/write(), recv()/send()7. 内核tcp数据传输7.1 TCP流量控制7.2 TCP拥塞控制——慢启动/拥塞避免/快速恢复/快速重传 8. shutdown()9. close()9… 文章目录 Posix API和网络协议栈使用TCP实现P2P通信1. socket()2. bind()3. listen()4. connect()5. accept()6. read()/write(), recv()/send()7. 内核tcp数据传输7.1 TCP流量控制7.2 TCP拥塞控制——慢启动/拥塞避免/快速恢复/快速重传 8. shutdown()9. close()9.1 正常情况9.2 主动关闭方在fin_wait_1状态下先收到FIN9.3 双方同时收到FIN报文 10. 使用TCP协议实现点对点通信学习参考 Posix API和网络协议栈使用TCP实现P2P通信 本文介绍了linux Posix API涉及网络编程的常用函数并解释其原理和涉及的网络协议栈。最后利用TCP三次握手中同时打开建立连接的情况实现了P2P通信。 1. socket() socke()的主要作用是分配fd和建立tcb(tcp control block)。 分配fd内部通过一个bitmap标记一个fd是否已被使用。建立tcballoc()此时还没有分配接受缓冲区和发送缓冲区。 TCB 是操作系统内核中用于跟踪每个 TCP 连接的核心数据结构包含了与连接相关的状态信息比如源地址、目标地址、端口号、窗口大小、序列号等。 2. bind() 将本地ip和和端口绑定到fd对应的tcb中。客户端fd如果bind了的话则本地端口就会固定。

  1. listen() 将监听套接字tcb中的status设置为TCP_STATUS_LISTEN。为监听套接字tcb分配两个队列半连接队列syn_queue和全连接队列accept_queue syn_queue存储还未完成三次握手的请求。Linux 中的 tcp_max_syn_backlog决定了 syn_queue 的最大容量。accpet_quque存储已经完成三次握手等待应用层调用accpet()的请求。如 Linux 中的 somaxconn决定了其容量。
    int listen(int sockfd, int backlog);其中backlog最早70年代指的是syn_queue队列的长度也就是收到SYN但是还没有完成三次握手的请求的队列长度。中间指的是两个队列的长度之和的最大值。现在指的是accpet队列最大长度。这样应用程序可以主要关注待处理连接请求的数量。 tcp连接的生命周期从什么时候开始 从收到第一个SYN报文的时候开始开始创建tcb连接开始建立。 第三次握手的数据包如何从半连接队列查找匹配的节点 每一个TCP报文段中都包含源ip、目的ip、源端口等五元组信息据此可以查找匹配。 如何解决SYN泛洪/DDOS攻击? 限制半连接队列的最大长度。
  2. connect() connect()用于客户端主动建立与对端的连接可能有两种情况。 三次握手主要是为了通信的同步交换序号信息保证之后的通信不丢失、不乱序。 正常主动打开 同时打开 适用于P2P通信需要双方同时调用connect()。 5. accept() 用于从全连接队列中取出一个连接并分配fd。 水平触发 每次只接受一个连接效率较低。 边缘触发 非阻塞IO 使用一个循环如果accept返回-1并且errno为EAGAIN或者EWOULDBLOCK则退出循环。 while (1) {fd accept(listen_fd, clnt_addr, clnt_addr_len);if (fd -1){if (errno EAGAIN || errno EWOULDBLOCK)break;}// 处理新连接 }6. read()/write(), recv()/send() 这些IO函数都是与系统内的接收缓冲区和发送缓冲区之间传输数据而非直接与网卡。tcp报文段的接受与发送和这些IO函数没有一对一的关系。
  3. 内核tcp数据传输 TCP协议头 7.1 TCP流量控制 滑动窗口 TCP使用了滑动窗口中的回退n自动重复请求机制。原理是当某个数据段未被正确接收则接收方不会确认其后续的数据段当发送方发现超时或者收到重复的ACK时会回退到未被确认的第一个数据段继续发送。 延迟确认 如果数据乱序到达可以等待一段时间在进行确认。 超时重传 7.2 TCP拥塞控制——慢启动/拥塞避免/快速恢复/快速重传 慢启动是 TCP 在建立连接或从网络拥塞中恢复时使用的拥塞控制算法旨在探测网络的可用带宽并逐步增加发送速率避免在一开始就超载网络。 发送端在收到一个ACK之前发送窗口的大小是由接收端接收窗口大小和本端拥塞窗口的大小决定的。 慢启动算法是指发送端拥塞窗口在到达慢启动阈值之前称之为慢启动姐阶段进行指数级增长。到达ssthreshslow start threshhold后进入拥塞避免阶段拥塞窗口进行线性增长。当超时重传时ssthresh变为当前拥塞窗口的一半并重新开始慢启动阶段。 快速恢复用于在丢包被检测到连续收到三个重复ACK后不必将拥塞窗口完全重置为 1 MSS而是通过调整 cwnd 和 ssthresh更快地恢复到稳定传输的状态。 连续收到三个重复ACK说明这与超时不同表明网络可能并未完全拥塞仍然存在一定的可用带宽。 具体来说当检测到丢包时发送方将 慢启动阈值 (ssthresh) 设置为当前 cwnd 的一半然后发送方将 cwnd 减小到 ssthresh 的大小同时跳过慢启动阶段直接进入拥塞避免阶段。收到连续三个重复ACK时也会对数据进行快速重传而非等到超时。
  4. shutdown() 进行半关闭关闭写端。不推荐使用因为它会使代码逻辑变复杂。
  5. close() 当通信两端有调用close()来关闭tcp连接时可能会发生以下三种交互情况。 9.1 正常情况 9.2 主动关闭方在fin_wait_1状态下先收到FIN 9.3 双方同时收到FIN报文 10. 使用TCP协议实现点对点通信 参考4. connect()中的同时打开模型。让双方同时在超时周期之内调用connect即可。演示代码如下 client1.c #include stdio.h #include string.h#include sys/socket.h #include arpa/inet.h #include unistd.hint main(int argc, char const *argv[]) {struct sockaddr_in local_addr {0}, peer_addr {0};int sock_fd socket(PF_INET, SOCK_STREAM, 0);local_addr.sin_family AF_INET;local_addr.sin_addr.s_addr htonl(INADDR_ANY);local_addr.sin_port htons(2000);peer_addr.sin_family AF_INET;peer_addr.sin_addr.s_addr inet_addr(127.0.0.1);peer_addr.sin_port htons(2001);if (bind(sock_fd, (struct sockaddr *)local_addr, sizeof local_addr) -1){perror(bind());close(sock_fd);return 1;}char message[100] hello I am KAKA;while (1){if (connect(sock_fd, (struct sockaddr *)peer_addr, sizeof peer_addr) -1){usleep(50);continue;}write(sock_fd, message, strlen(message));close(sock_fd);break;}return 0; } client2.c #include stdio.h #include string.h#include sys/socket.h #include arpa/inet.h #include unistd.hint main(int argc, char const *argv[]) {struct sockaddr_in local_addr {0}, peer_addr {0};int sock_fd socket(PF_INET, SOCK_STREAM, 0);local_addr.sin_family AF_INET;local_addr.sin_addr.s_addr htonl(INADDR_ANY);local_addr.sin_port htons(2001);if (bind(sock_fd, (struct sockaddr *)local_addr, sizeof local_addr) -1){perror(bind());close(sock_fd);return 1;}peer_addr.sin_family AF_INET;peer_addr.sin_addr.s_addr inet_addr(127.0.0.1);peer_addr.sin_port htons(2000);char buf[100];int received;while (1){if (connect(sock_fd, (struct sockaddr *)peer_addr, sizeof peer_addr) -1){usleep(50);continue;}if ((received read(sock_fd, buf, sizeof buf - 1)) ! 0){if (received -1){perror(read());close(sock_fd);return 1;}buf[received] 0;printf(from peer:\n%s\n, buf);}close(sock_fd);break;}return 0; }学习参考 学习更多相关知识请参考零声 github。