• TCP套接字【网络】


    TCP常见接口

    创建套接字:(TCP/UDP)

    int socket(int domain, int type, int protocol);
    

    inet_aton,将字符串IP转换成整数IP

    int inet_aton(const char *cp, struct in_addr *inp);
    

    监听套接字:(TCP,服务器)

    int listen(int sockfd, int backlog);
    

    TCP服务器在与客户端进行网络通信之前,服务器需要先获取到客户端的连接请求,获取连接的函数叫做accept

    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    

    参数说明:

    • sockfd:特定的监听套接字,表示从该监听套接字中获取连接。
    • addr:对端网络相关的属性信息,包括协议家族、IP地址、端口号等。
    • addrlen:调用时传入期望读取的addr结构体的长度,返回时代表实际读取到的addr结构体的长度,这是一个输入输出型参数

    return val :

    • 获取连接成功返回接收到的套接字的文件描述符,获取连接失败返回-1,同时错误码会被设置。

    如何理解accept函数返回的套接字?

    • 调用accept函数获取连接时,是从监听套接字当中获取的。如果accept函数获取连接成功,此时会返回接收到的套接字对应的文件描述符

    监听套接字与accept函数返回的套接字

    1、监听套接字:用于获取客户端发来的连接请求。accept函数会不断从监听套接字当中获取新连接。
    2、accept函数返回的套接字:用于为本次accept获取到的连接提供服务。监听套接字的任务只是不断获取新连接,而真正为这些连接提供服务的套接字是accept函数返回的套接字,而不是监听套接字

    telnet 是一个基于网络的命令行工具,用于远程登录到另一台计算机

    inet_ntop,将整数IP转换成字符串IP

      const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
    
    • af:地址族,指定要转换的地址类型。常见的值有 AF_INET(IPv4)和 AF_INET6(IPv6)。

    • src:指向包含原始网络地址的缓冲区的指针。

    • dst:指向目标缓冲区的指针,该缓冲区将接收转换后的文本表示。如果 dst 为 NULL,则 inet_ntop 将分配一个足够大的缓冲区,并返回指向该缓冲区的指针。

    • size:目标缓冲区的大小

    建立连接:(TCP,客户端)

    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    

    inet_pton,将一个点分十进制的IP地址字符串转换为网络字节顺序的数值形式

     int inet_pton(int af, const char *src, void *dst);
    

    af:指定地址族,可以是 AF_INET(IPv4)或 AF_INET6(IPv6)。
    src:指向一个以 null 结尾的字符串,包含要转换的IP地址。
    dst:指向一个用于存储转换后的数值地址的缓冲区。

    服务端

    服务端创建套接字

    TCP服务器创建套接字的做法与UDP服务器是一样的

    服务端绑定

    创建完套接字后我们还需要调用bind函数进行绑定操作

    如何绑定
    定义一个struct sockaddr_in结构体,将服务器网络相关的属性信息填充到该结构体当中,比如协议家族、IP地址、端口号等。
    填充服务器网络相关的属性信息时,协议家族对应就是AF_INET,端口号就是当前TCP服务器程序的端口号。在设置端口号时,需要调用htons函数将端口号由主机序列转为网络序列。
    在设置服务器的IP地址时,可以设置为本地环回127.0.0.1,表示本地通信。也可以设置为公网IP地址,表示网络通信。
    如果使用的是云服务器,那么在设置服务器的IP地址时,不需要显示绑定IP地址,直接将IP地址设置为INADDR_ANY即可,此时服务器就可以从本地任何一张网卡当中读取数据。此外,由于INADDR_ANY本质就是0,因此在设置时不需要进行网络字节序的转换。
    填充完服务器网络相关的属性信息后,需要调用bind函数进行绑定。绑定实际就是将文件与网络关联起来,如果绑定失败也没必要进行后续操作了,直接终止程序即可。

    服务端监听

    TCP服务器是面向连接的,客户端在正式向TCP服务器发送数据之前,需要先与TCP服务器建立连接,然后才能与服务器进行通信。

    因此TCP服务器需要时刻注意是否有客户端发来连接请求,此时就需要将TCP服务器创建的套接字设置为监听状态
    listen函数可以设置套接字为监听状态

    服务端获取连接

    TCP服务器在与客户端进行网络通信之前,服务器需要先获取到客户端的连接请求

    accept是获取连接的函数

    服务端处理请求

    现在TCP服务器已经能够获取连接请求了,下面当然就是要对获取到的连接进行处理

    为客户端提供服务的不是监听套接字,因为监听套接字获取到一个连接后会继续获取下一个请求连接,为对应客户端提供服务的套接字实际是accept函数返回的套接字

    客户端

    客户端创建套接字

    客户端不需要进行绑定和监听:

    服务端要进行绑定:
    服务端的IP地址和端口号必须要众所周知,不能随意改变。客户端虽然也需要IP地址和端口号,tcp的客户端是需要bind端口号,但是不需要显示的bind端口号 ,由操作系统随机选择端口号

    服务端需要进行监听
    服务端需要通过监听来获取新连接,但是不会有人主动连接客户端,因此客户端是不需要进行监听操作的

    客户端必须要知道它要连接的服务端的IP地址和端口号,因此客户端除了要有自己的套接字之外,还需要知道服务端的IP地址和端口号,这样客户端才能够通过套接字向指定服务器进行通信

    客户端连接服务器并发起请求

    当客户端创建完套接字后就可以向服务端发起连接请求。

    调用connect函数向服务端发起连接请求时

    代码

    单进程版本
    多进程版本

    多进程版本关于sockfd
    在这里插入图片描述

    线程版本
    线程池版本

  • 相关阅读:
    QT基础介绍
    视野修炼-技术周刊第56期
    141. 环形链表
    山东大学单片机原理与应用实验 4.5 8255并行I/O扩展及交通信号灯控制实验
    在Gin框架中加入Zap日志中间件
    lua学习笔记
    ASEMI整流桥D3KB100参数,D3KB100规格,D3KB100封装
    基于扩频技术的MPEG-2视频水印算法matlab仿真
    iOS dSYM详解和分析crash,ips文件
    通讯网关软件022——利用CommGate X2MQTT实现MQTT访问MSSQL服务器
  • 原文地址:https://blog.csdn.net/qq_73478334/article/details/141832299