[Network Programming] Summary of commonly used functions

Socket format

Universal socket format

/* POSIX.1g 规范规定了地址族为2字节的值.  */
typedef unsigned short int sa_family_t;
/* 描述通用套接字地址  */
struct sockaddr{
    sa_family_t sa_family;  /* 地址族.  16-bit*/
    char sa_data[14];   /* 具体的地址值 112-bit */
  }; 

IPv4 socket address format


/* IPV4套接字地址,32bit值.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };
  
/* 描述IPV4的套接字地址格式  */
struct sockaddr_in
  {
    sa_family_t sin_family; /* 16-bit AF_INET*/
    in_port_t sin_port;     /* 端口口  16-bit*/
    struct in_addr sin_addr;    /* Internet address. 32-bit */


    /* 这里仅仅用作占位符,不做实际用处  */
    unsigned char sin_zero[8];
  };

IPv6 socket address format

struct sockaddr_in6
  {
    sa_family_t sin6_family; /* 16-bit AF_INET6*/
    in_port_t sin6_port;  /* 传输端口号 # 16-bit */
    uint32_t sin6_flowinfo; /* IPv6流控信息 32-bit*/
    struct in6_addr sin6_addr;  /* IPv6地址128-bit */
    uint32_t sin6_scope_id; /* IPv6域ID 32-bit */
  };

Local socket address format

struct sockaddr_un {
    unsigned short sun_family; /* 固定为 AF_LOCAL */
    char sun_path[108];   /* 路径名 */
};

Common socket API

socket create socket

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
/*
参数:
    domain:选择协议族PF_INET、PF_INET6 以及 PF_LOCAL 等
    type: 明确交流语义
        SOCK_STREAM: 有序,可靠基于连接的字节流;TCP
        SOCK_DGRAM:面向无连接的不可靠的数据报; UDP
        SOCK_RAW: 表示的是原始套接字。
    protocol:指定通信协议,已废弃,一般写成0 
*/
/*
返回值:
    创建成功,返回文件描述符
    失败,返回-1
*/

bind bind socket and socket address

Function: Bind the parameters sockfd and addr together, so that sockfd, the file descriptor for network communication, listens to the address and port number described by addr. struct sockaddr * is a universal pointer type. The addr parameter can actually accept sockaddr structures of multiple protocols, and their lengths are different, so the third parameter addrlen is required to specify the length of the structure.

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
参数:
    sockfd: 待绑定的套接字,文件描述符
    addr: 套接字地址,构造出IP地址+端口号
    addrlen: 绑定的套接字地址的大小
*/
/*
返回值:
    创建成功,返回0
    失败,返回-1
*/
/*Example*/
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr)); //将整个结构体清零
servaddr.sin_family = AF_INET; //设置地址类型为AF_INET,这个宏表示本地的任意IP地址,
                               //因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,
                               //这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6666);

listen converts active socket to passive socket

Role: A typical server program can serve multiple clients at the same time. When a client initiates a connection, the server's accept () returns and accepts the connection. If a large number of clients initiate a connection and the server has no time to process it, it has not yet accepted The client is in the connection waiting state, listen () declares that sockfd is in the listening state, and at most backlog clients are allowed to be in the connection waiting state. If more connection requests are received, they are ignored. listen () returns 0 on success and -1 on failure.

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);

/*
参数:
    sockfd: 套接字,文件描述符
    backlog:排队建立3次握手队列和刚刚建立3次握手队列的链接数和 
    cat /proc/sys/net/ipv4/tcp_max_syn_backlog //查看系统默认backlog
*/
/*
返回值:
    创建成功,返回0
    失败,返回-1
*/

accept to accept the connection

Function: After the three-way handshake is completed, the server calls accept () to accept the connection. If there is no client connection request when the server calls accept (), it blocks and waits until a client connects. addr is an outgoing parameter, and the address and port number of the client are transmitted when accept () returns. The addrlen parameter is an incoming and outgoing parameter (value-result argument). The incoming length of the buffer addr provided by the caller is used to avoid buffer overflow. The outgoing length is the actual length of the client address structure. It may not fill the buffer provided by the caller). If NULL is passed to the addr parameter, it means that the client's address is not concerned.

#include <sys/types.h> 		/* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*
参数:
    sockfd: 套接字,文件描述符
    addr: 传出参数,返回链接客户端地址信息,含IP地址和端口号
    addrlen: 传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
*/
/*
返回值:
    创建成功,返回新的文件描述符,用于通信
    失败,返回-1
*/

The whole is a while loop, each loop processing a client connection. Since cliaddr_len is an incoming and outgoing parameter, the initial value should be re-assigned before each accept () call. The parameter listenfd of accept () is the previous file descriptor, and the return value of accept () is another file descriptor connfd. After that, it communicates with the client through this connfd, and finally closes connfd to disconnect without Close listenfd and return to the beginning of the loop again. Listenfd is still used as the accept parameter. accept () returns a file descriptor on success, and -1 on error.

/*示例*/
while (1) {
	cliaddr_len = sizeof(cliaddr);
	connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
	n = read(connfd, buf, MAXLINE);
	......
	close(connfd);
}

connect

The client needs to call connect () to connect to the server. The parameters of connect and bind are the same. The difference is that the parameter of bind is its own address, and the parameter of connect is the address of the other party. connect () returns 0 on success and -1 on error.

#include <sys/types.h> 					/* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
参数:
    sockfd: 套接字,文件描述符
    addr: 传入参数,指定服务器端地址信息,含IP地址和端口号
    addrlen: 传入参数,传入sizeof(addr)大小
*/
/*
返回值:
    创建成功,返回0
    失败,返回-1
*/

Guess you like

Origin www.cnblogs.com/Trevo/p/12615848.html