study notes: high performance linux server programming

1:linux网络API分为:socker地址API,socker基础API,网络信息API

  1,socker地址API:包含IP地址和端口(ip, port)。表示TCP通信的一端。

  2,socker基础API:创建/命名/监听socker,接收/发起链接,读写数据,获取地址信息,检测带外标记和读取/设置socker选项。sys/socket.h

  3,网络信息API:主机名和IP地址的转换,服务名和端口号的转换。netdb.h

2:socket和API的函数 和 相关知识。

  1,函数。

1 IP地址转换函数
  <arpa/inet.h>
  in_addr_t inet_addr( const char* strptr );  // 格式转换:十进制字符串IP -> 网络字节序(大端)IP
  int inet_aton( const char* cp, struct in_addr* inp );  // 格式转换:如上,但将数据保存到参数inp中
  char* inet_ntoa( struct in_addr in );  //  格式转换:网络字节序(大端)IP -> 十进制字符串IP
  int inet_pton( int af, const char* src, void* dst ); // 格式转换:字符串IP地址 -> 网络字节序(大端)整数IP
  const char* inet_ntop( int af, const void* src, char* dst, socklen_t cnt );  格式转换:网络字节序(大端)整数IP -> 字符串IP地址
  // inet_ntoa函数不可重入。
  // inet_ntop返回目标储存单元的地址。
2 创建socket
  <sys/types.h> <sys/socket.h>
  int socket( int domain, int type, int protocol );
  // 1 参数domain:使用的底层协议族。
  // 2 参数type:指定服务类型。SOCK_STREAM(TCP) SOCK_UGRAM(UDP)
  // 3 参数protocol:指定具体协议。一般默认为0.(前面参数已经确定了协议)
  // 4 返回:socket文件描述符。失败-1,设置errno
3 命名socket
  <sys/types.h> <sys/socket.h>
  int bind( int sockfd, const struct sockaddr* my_addr, socklen_t addrlen );
  // 1 参数addrlen:socket地址长度。
  // 2 返回:成功0,失败-1,设置errno
4 监听socket
  <sys/socket.h>
  int listen( int sockfd, int backlog );
  // 1 参数sockfd:指定被监听socket
  // 2 参数backlog:监听队列最大长度。典型值:5
5 接收链接。
  <sys/types.h> <sys/socket.h>
  int accept( int sockfd, struct sockaddr* addr, socklen_t* addrlen );
  // 1 参数sockfd:执行过listen的socket。
  // 2 参数addr:被接受链接的远程socket地址。
  // 3 参数addrlen:地址长度。
  // 4 返回:成功新的链接socket,失败-1设置errno
  // 5 accept只从监听队列取出连接,并不检测网络状态。
6 发起链接
  <sys/types.h> <sys/socket.h>
  int connect( int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen );
  // 1 参数sockfd:由socket系统调用返回一个socket
  // 2 参数serv_addr:服务器监听的socket地址。
  // 3 返回:成功0,失败-1设置errno
7 关闭连接
  <unistd.h>
  int close( int fd );
  // 1 不会立即关闭,只是将引用减一。只有引用为0时才会真正关闭。
  <sys/socket.h>
  int shutdown( int sockfd, int howto );
  // 1 立即关闭连接。
  // 2 参数howto:决定函数的行为。SHUT_RD/WR/RDWR:可以分别控制读写关闭。
  // 3 返回:成功0,失败-1设errno
8 TCP数据读写。
  <sys/types.h> <sys/socket.h>
  ssize_t recv( int sockfd, void* buf, size_t len, int flags );  // 返回:实际读取到的数据长度。失败-1errno
  ssize_t send( int sockfd, const void* buf, size_t len, int flags );  // 返回:实际写入的数据长度。失败-1reeno
  // 1 参数buf,len:缓冲区的地址和大小。
  // 2 参数flags:数据收发额外控制。通常设0.
9 UDP数据读写。
  <sys/types.h> <sys/socket.h>
  ssize_t recvfrom( int sockfd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t *addrlen );
  ssize_t sendto( int sockfd, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t *addrlen );
  // 1 参数src/dest_addr:确定发送/接收端地址。(因UDP没有连接概念)
  // 2 这两个函数同样可以应用于TCP读写数据。
10 通用数据读写函数。
  <sys/socket.h>
  ssize_t recvmsg( int sockfd, struct msghdr* msg, int flags );
  ssize_t sendmsg( int sockfd, struct msghdr* msg, int flags );
  struct msghdr{
    void* msg_name;             // socket 地址
    socklen_t msg_namelen;    // 地址长度
    struct iovec* msg_iov;      // 分散的内存块
    int msg_iovlen;             // 分散内存块的数量
    void* msg_control;      // 辅助数据地址
    socklen_t msg_controllen;   // 辅助数据大小
    int msg_flags;              // 保存函数flag参数
  }
11 确定下一个数据是否时带外数据。
  <sys/socket.h>
  int sockatmark( int sockfd );  // 返回:带外1,否则0
12 获取地址信息。
  <sys/socket.h>
  int getsockname( int sockfd, struct sockaddr* address, socklen_t* address_len );  // 本端
  int getpeername( int sockfd, struct sockaddr* address, socklen_t* address_len );  // 远端
  // 1 返回:成功0,失败-1errno
13 获取/设置socket选项
  <sys/socket.h>
  int getsockopt( int sockfd, int level, int option_name, void* option_value, socklen_t* restrict option_len );
  int setsockopt( int sockfd, int level, int option_name, const void* option_value, socklen_t* restrict option_len );
  // 1 参数level:具体协议选项。
  // 2 返回:成功0,失败-1errno。

// 此后为网络信息API
14 获取主机完整信息。
  <netdb.h>
  struct hostent* gethostbyname( const char* name );  // 通过主机名称获取
  struct hostent* gethostbyaddr( const void* addr, size_t len, int type );  //通过IP地址获取
  // 1 参数type:IP地址的类型。
  // 2 返回:主机信息。
15 获取服务的完整信息。
  <netdb.h> 
  struct servent* getservbyname( const char* name, const char* proto );  // 通过名字获取
  struct servent* getservbyport( int port, const char* proto );  // 通过端口号获取
  // 1 参数proto:确定服务类型:UDP/TCP
16 获取主机和服务的综合函数。
  int getaddrinfo( const char* hostname, const char* service, const struct addrinfo* hints, struct addrinfo** result );
  int getnameinfo( const struct sockaddr* sockaddr, socklen_t addrlen, char* host, socklen_t hostlen, char* serv, socklen_t servlen, int flags );

 

   2,88-94在完成初版IM时,需要进行测试

3:高级IO(高编已由函数省略)

  1,函数

1 两个文件描述符之间直接传递数据
  ssize_t sendfile( int out_fd, int in_fd, off_t* offset, size_t count );
  // 1 参数count:传输字节数
  // 2 返回:成功返回传输字节数,失败-1errno
  // 3 in_fd:必须时真实文件,out_fd:必须是socket
2 两个文件描述符之间移动数据。零copy操作
  ssize_t splice( int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, size_t len, unsigned int flags );  // 具体需要再了解和使用。
3 两个管道文件描述符之间复制数据。零copy操作
  ssize_t tee( int fd_in, int fd_out, size_t len, unsigned int flags );
4

 

4:

5

6

7

8

9

10

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。