zoukankan      html  css  js  c++  java
  • linux第5天 socket api

      IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件<netinet/in.h>中

      通用地址结构用来指定与套接字关联的地址。以sockaddr命名

    我们进行TCP编程的时候,通常是用sockaddr_in,但提供的API函数是通用地址结构,所以,传递参数时要进行强转.

    socket编程时,服务端的常规流程是socket->bind->listen->accept,而客户端的流程是socket->connect

    socket 创建一个套接字用于通信

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

     返回值注意:在listen函数调用前都是主动套接字,调用后调用之后变成被动套接字.

    bind  绑定一个本地地址到套接字

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

    其中struct sockaddr *addr

    man 7 ip

    struct sockaddr_in {
      sa_family_t sin_family; /* address family: AF_INET */
      in_port_t sin_port; /* port in network byte order */
      struct in_addr sin_addr; /* internet address */
    };

      struct in_addr {
      uint32_t s_addr; /* address in network byte order */
    };

    注意:设置IP地址的时候需要用转换函数in_addr_t inet_addr(const char *cp);

           设置端口的时候需要用到网络字节序,htons,htonl.

           端口的设置 addr.sin_addr.s_addr = htons(8001)

    listen

     一般来说,listen函数应该在调用socket和bind函数之后,调用函数accept之前调用。

      对于给定的监听套接口,内核要维护两个队列:

      1、已由客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程

      2、已完成连接的队列

    accept

     从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞。

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

    注意参数addr,这个addr是已连接客户端的信息,包括IP地址和端口,与bind函数里所使用的addr不一样.

    参数addrlen,表示value-result,需要提前指定大小(socklen_t addrlen = sizeof(struct sockaddr_in)),然后以地址的方式传进去,.

    当函数被调用时,结构大小是一个值(value, 此值告诉内核该结构的大小,使内核在写此结构时不至于越界),

    当函数返回时,结构大小又是一个结果(result,它告诉进程内核在此结构中确切存储了多少信息),这种参数叫做值-结果参数(value-result)。

    connect函数  

    建立一个连接至addr所指定的套接字

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

    设置与服务端的bind函数一致.

      服务器端尽可能使用SO_REUSEADDR

      在绑定之前尽可能调用setsockopt来设置SO_REUSEADDR套接字选项。

    使用SO_REUSEADDR选项可以使得不必等待TIME_WAIT状态消失就可以重启服务器

    关于sockfd与connfd

    sockfd是一开始socket函数打开的一个新的套接字的文件描述符,需要提供给bind函数,listen函数,accept函数使用,

    当有客户端连接,accept函数返回后,将产生一个新的套接字的描述符(connfd,而非sockfd),用来专门与客户端进行通信,

    总的来说,sockfd就是服务器用来让客户端进行连接的套接字,而connfd是专门为服务器与客户端进行通信的.

    服务器行多并发的时候,需要一个通道进行连接,另一个通道进行通信.

    当客户端只有一个时,可以将sockfd与connfd合二为一,但客户端多的时候,这样的设计会让tcp通信变量混乱.故而分开设计之.

  • 相关阅读:
    C#listbox使用方法
    poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 黑白无常
  • 原文地址:https://www.cnblogs.com/c-slmax/p/5243633.html
Copyright © 2011-2022 走看看