zoukankan      html  css  js  c++  java
  • linux网络编程系列TCP及常用接口分析

    TCP编程示例图:


    头文件:

    常用头文件"arpa/inet.h", "sys/socket.h","netinet/in.h"

    函数原型:

    int socket(int family, int type, int protocol)
    

    family:通信协议族,IP protocol family为AF_INET(PF_INET),值是2;

    type:套接字类型(连接类型)。

    SOCK_STREAM(1)为Sequenced, reliable, connection-based byte streams(TCP);

    SOCK_DGRAM(2)为Connectionless, unreliable datagrams of fixed maximum length(UDP);

    其他还有SOCK_RAW(3), SOCK_RDM(4), SOCK_SEQPACKET(5),SOCKET_PACKET(10)。

    protocol:不解释了,没理解,一般写为0,系统自动选择合适的协议。返回:套接字描述符。

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

    connect:客户端调用;servaddr套接口地址结构,包含有服务器的IP地址和端口号;返回0成功,-1出错;每当connect失败,都必须关闭套接口,重新调用socket。

    int bind(int sockfd, const struct sockaddr* myaddr, socklen_t addrlen)

    bind:服务端调用,给套接口分配一个本地协议地址;myaddr包含本地分配的ip和端口;返回0成功,-1出错。客户端不调用bind由内核随意分配一个端口,而服务端必须调用明确指出端口。

    int listen(int sockfd, int backlog)
    

    listen:socket函数创建套接口默认为主动套接口(要发起连接的),listen会将未连接的套接口转换成被动套接口(接收连接),返回-1出错0成功。

    int accept(int sockfd, struct sockaddr* cliaddr, socklen_t* addrlen)
    

    accept:从已完成的连接队列头部返回一个已完成连接;成功返回内核自动生成的一个全新描述字代表与客户端的TCP连接,第一个参数sockfd常称为监听套接口,返回值称为已连接套接口,返回-1出错。cliaddr为客户端的协议地址,addrlen为该地址大小。一个服务器常常只生成一个监听套接口且一直存在,直到该服务器关闭。内核为每个被接受的客户连接创建一个已连接套接口(三路握手已完成的连接)。

    监听套接口的两个队列:


    int close(int sockfd)
    

    close:将套接口sockfd做上已关闭标记,并立即返回。该描述字不能再用作read或write的参数,但TCP会继续发送已排队待发的数据,然后按照TCP连接终止序列进行操作。

    数据读写:

    标准读写

    ssize_t write(int fd, const void *buf, size_t n)
    ssize_t read (int fd, void *buf, size_t n)

    网络读写

    ssize_t send (int fd, const void *buf, size_t n, int flags)
    ssize_t recv (int fd, void *buf, size_t n, int flags)

    何时阻塞:

    •写阻塞,send buffer is full
    •读阻塞,receive buffer is empty

    常用结构:

    socklen_t表示套接字的大小,4Byte,是一个uint32类型。

    struct sockaddr表示套接字的连接地址,通常用struct sockaddr_in代替。二者大小相同,sockaddr_in用了多余的char数组来补齐大小。

    struct sockaddr
    {
    sa_family_t sa_family;//2个字节,地址协议族,unsigned short int
    char sa_data[14];//地址
    }
    struct sockaddr_in
      {
        sa_family_t sin_family; //2Byte
        in_port_t sin_port;     /* Port number.  2Byte*/ 
        struct in_addr sin_addr;    /* Internet address.  4Byte*/
    
        /* Pad to size of `struct sockaddr'.  */
        unsigned char sin_zero[sizeof (struct sockaddr) -
             __SOCKADDR_COMMON_SIZE -
             sizeof (in_port_t) -
             sizeof (struct in_addr)];
      };
    typedef uint32_t in_addr_t;
    struct in_addr
    {
        in_addr_t s_addr;
    };
    #define __SOCKADDR_COMMON_SIZE  sizeof(unsigned short int)
    
    辅助函数:
    char *inet_ntoa (struct in_addr __in)

    将IP地址由网络字节序转为可理解的点分十进制(net to ascii)

    int inet_pton (int af, const char* cp, void* buf)

    将点分十进制ip转为网络字节序,af为地址协议族(AF_INET),cp为ip地址(10.8.3.2), buf为保存转换结果的地址。常用如下:

    struct sockaddr_in addr;
    inet_pton(AF_INET, "10.3.17.75", &addr.sin_addr);
    in_addr_t inet_addr (const char *cp)

    同inet_pton效果相同,将ip转为网络字节序

    struct sockaddr_in sin;
    sin.sin_addr.s_addr = inet_addr("10.17.25.34");


  • 相关阅读:
    jvm 垃圾收集算法
    jvm 判断对象死亡
    jvm 内存分配
    jvm 对象奥秘
    mysql事务测试及delete和update是使用行级锁,还是表级锁
    sql语句中where后边的哪些条件会使索引失效 -- SQL语句优化
    java nio详解
    mysql数据库优化概述详解
    java 序列化和反序列化
    java io框架详解
  • 原文地址:https://www.cnblogs.com/whuqin/p/4982012.html
Copyright © 2011-2022 走看看