C/C++ TCP网络通信基本流程

通信流程如下:

服务端:

  1. 调用socket函数创建socket(监听socket)
  2. 调用bind函数将socket绑定到某个IP和端口
  3. 调用listen函数开启监听
  4. 当有客户端请求连接上来时,调用accept函数接收连接,产生一个新的socket
  5. 基于新的socket调用recve或者send函数,开始与客户端进行数据交互
  6. 通信结束后,调用close函数关闭监听socket

客户端:

  1. 调用socket函数创建客户端socket
  2. 调用connect函数尝试连接服务器
  3. 连接成功后调用send或recv函数,开始与服务器进行数据交互
  4. 通信结束后,调用close函数关闭监听socket

如下图所示

socket函数族

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

    功能:创建通信端点并返回描述符

    参数domain: 指定通信域; 这将选择用于通信的协议族。协议族包含如下

    Name Purpose Man page
    AF_UNIX, AF_LOCAL Local communication unix(7)
    AF_INET IPv4 Internet protocols ip(7)
    AF_INET6 Pv6 Internet protocols ipv6(7)
    AF_IPX IPX - Novell protocols
    AF_NETLINK Kernel user interface device netlink(7)
    AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
    AF_AX25 Amateur radio AX.25 protocol
    AF_ATMPVC Access to raw ATM PVCs
    AF_APPLETALK Appletalk ddp(7)
    AF_PACKET Low level packet interface packet(7)

    参数type: 指定的类型,该类型指定通信语义。类型有:

    SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported
    SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a fixed maximum length).
    SOCK_SEQPACKET Provides a sequenced, reliable, two-way connection-based data transmission path for datagrams of fixed maximum length; a consumer is required to read an entire packet with each input system call.
    SOCK_RAW Provides raw network protocol access.
    SOCK_RDM Provides a reliable datagram layer that does not guarantee ordering.
    SOCK_PACKET Obsolete and should not be used in new programs; see packet(7).

    前两个分别对应TCP和UDP类型的socket

    参数protocol: 指定协议,常用有IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC,协议和socket的类型要匹配。0会选择type对应的默认类型。一般写0。

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

    功能:连接服务器

    sockfd:socket套接字

    addr: 一个地址结构体的const指针,指向要绑定给sockfd的地址,结构体的结构和地址协议相符

    ipv4的地对应的

    struct sockaddr_in {
       sa_family_t    sin_family; /*地址族: AF_INET */
       in_port_t      sin_port;   /*网络字节序的端口号 */
       struct in_addr sin_addr;   /*internet 地址 */
    };
     /* Internet 地址. */
    struct in_addr {
       uint32_t       s_addr;     /* 网络字节序的地址 */
    };
    

    addrlen: addr结构体的长度

  3. int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    功能:将socket绑定到某个IP和端口

    sockfd:为 socket()函数创建返回的fd

    addr:指向一个包含了ip地址 端口等信息

    addrlen:sockaddr的长度

    成功返回0,失败返回-1

  4. int listen(int s, int backlog);

    s:要监听的socket的描述符

    backlog:指定未完成连接队列的最大长度

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

    功能:接收连接,产生一个新的socket

    sockfd:服务器socket描述字

    addr:获取的客户端的ip地址、端口信息和协议族等信息

    addrlen:addr长度

    返回值:新连接客户端套接字的描述符

posted @ 2022-03-28 02:13  DarkH  阅读(1253)  评论(0编辑  收藏  举报