2.2.3 Posix API与网络协议栈

简介: 2.2.3 Posix API与网络协议栈

1.connect(fd, serveraddr, size)
a. fd -> tcb
  syn
///
2.listen
a. listenfd -> tcb
b. tcb -> listen
//
3.accept
a. while(acceptqueue == NULL) {
  pthread_cond_wait();
}
b. *tcb = get_tcb_from(acceptqueue);
c. clientfd = get_fd_fdtable();
d. tcb -> clientfd;
return clientfd;

如何通过网络数据包,查找半链接队列的节点

五元组(sip, dip, sport, dport, proto)

端口65535个,如何做百万级别的连接

连接 tcb 五元组

连接断开

FIN包一般是携带包,比如携带在最后一次发送数据包的标志位上,如果一直没有发送数据,则会单独发送FIN包。

大量close_wait状态?没有及时调用close();

两端同时调用close() ? 进入CLOSING状态(下图的同时关闭状态)

思考:

使用tcpdump抓取三次握手

SYN_SENT如何转为SYN_RECV ? (同时打开)

listenfd能不能够connect ?

这里使用一个拿来即用的TCP测试程序:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
int main(void)
{
    //初始化套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = htons(8888);
    int ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
    if (ret < 0)
    {
        perror("bind");
        return -1;
    }
    ret = listen(listenfd, 5);
    if (ret < 0)
    {
        perror("listen");
        return -1;
    }
    struct sockaddr_in client_address;
    socklen_t client_addrlength = sizeof(client_address);
    int connfd = accept(listenfd, (struct sockaddr *)&client_address, &client_addrlength);
    if (connfd < 0)
    {
        perror("accept");
    }
    printf("The connection is successful : %d\n", connfd);
    char buf[1024] = {0};
    ret = recv(connfd, buf, 1024, 0);
    if (ret <= 0) {
        perror("recv");
    }
    printf("recv: %s\n", buf);
    close(connfd);
    close(listenfd);
    return 0;
}

程序监听在8888端口上,我们使用网络调试助手连接一下,并使用tcpdump查看8888端口的状态:

上面的是建立连接抓取的包,下面的是服务端主动断开连接发送的网络包。

仍然使用上面那个服务端程序,使用下面这个客户端程序连接,看看listenfd能不能connect:

int main(void)
{
    //初始化套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0)
    {
        perror("socket");
        return -1;
    }
    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = htonl(INADDR_ANY);
    address.sin_port = htons(8889);//这里绑定在8889端口
    int ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
    if (ret < 0)
    {
        perror("bind");
        return -1;
    }
    ret = listen(listenfd, 5);
    if (ret < 0)
    {
        perror("listen");
        return -1;
    }
    struct sockaddr_in srv_addr;
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    srv_addr.sin_port = htons(8888);//连接8888
    //使用listenfd
    if(-1 == connect(listenfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)))
    {
        perror("connect");
        return 1;
    } else {
        printf("connect success!");
    }
    return 0;
}

运行发现连接失败:

gaoyuelong@ubuntu:~/23040voice/06/test$ ./client 
connect: Transport endpoint is already connected

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:https://ke.qq.com/course/417774?flowToken=1020253

相关文章
|
6月前
|
弹性计算 负载均衡 网络协议
这种情况可能是由于阿里云的API服务出现了短暂的故障或者网络波动导致的
【2月更文挑战第20天】这种情况可能是由于阿里云的API服务出现了短暂的故障或者网络波动导致的
134 1
|
6月前
|
分布式计算 API Linux
通义千问API:找出两篇文章的不同
本章我们将介绍如何利用大模型开发一个文档比对小工具,我们将用这个工具来给互联网上两篇内容相近但版本不同的文档找找茬,并且我们提供了一种批处理文档比对的方案
|
2天前
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
21 13
|
2月前
|
网络协议 网络架构 数据格式
TCP/IP基础:工作原理、协议栈与网络层
TCP/IP(传输控制协议/互联网协议)是互联网通信的基础协议,支持数据传输和网络连接。本文详细阐述了其工作原理、协议栈构成及网络层功能。TCP/IP采用客户端/服务器模型,通过四个层次——应用层、传输层、网络层和数据链路层,确保数据可靠传输。网络层负责IP寻址、路由选择、分片重组及数据包传输,是TCP/IP的核心部分。理解TCP/IP有助于深入掌握互联网底层机制。
353 2
|
3月前
|
JavaScript 网络协议 API
【Azure API 管理】Azure APIM服务集成在内部虚拟网络后,在内部环境中打开APIM门户使用APIs中的TEST功能失败
【Azure API 管理】Azure APIM服务集成在内部虚拟网络后,在内部环境中打开APIM门户使用APIs中的TEST功能失败
|
3月前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API三种搭建神经网络的方式及以mnist举例实现
使用Keras API构建神经网络的三种方法:使用Sequential模型、使用函数式API以及通过继承Model类来自定义模型,并提供了基于MNIST数据集的示例代码。
51 12
|
3月前
|
缓存 网络协议 Linux
扩展Linux网络栈
扩展Linux网络栈
68 3
|
3月前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API两种训练GAN网络的方式
使用Keras API以两种不同方式训练条件生成对抗网络(CGAN)的示例代码:一种是使用train_on_batch方法,另一种是使用tf.GradientTape进行自定义训练循环。
36 5
|
3月前
|
Java API 网络安全
探索Java中的Stream API:从基础到高级应用云计算与网络安全:技术融合与挑战
【8月更文挑战第27天】在Java的海洋中,Stream API犹如一艘强大的船,让开发者能以声明式的方式处理集合数据。本文将启航,先带你了解Stream的基本概念和用法,再深入探讨其高级特性,如并行流、管道操作以及性能考量。我们将通过具体代码示例,展示如何高效利用Stream API简化数据处理流程,提升代码的可读性和性能。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往更优雅编程风格的大门。
|
3月前
|
SQL 网络协议 安全
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题
【Azure API 管理】APIM集成内网虚拟网络后,启用自定义路由管理外出流量经过防火墙(Firewall),遇见APIs加载不出来问题