zoukankan      html  css  js  c++  java
  • Linux高性能服务器编程:网络编程基础API

    1. socket地址API

    大端字节序:一个整数的高位字节存储在内存的低地址处,低位字节存储在内存的高地址处。

    小端字节序:整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地址处。

    现代PC机采用小端字节序,又称为主机字节序。

    大端字节序主要在网络上传输,称为网络字节序。

    2. 创建socket

    socket是可读、可写、可控制、可关闭的文件描述符。

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

    domain: 表示使用哪个底层协议族,对TCP/IP而言,该参数应该设置为PF_INET。

    type: 表示服务类型,流服务:SOCK_STREAM, 数据报服务:SOCK_DGRAM。

    protocol:0

    3.命名socket

    采用bind函数。

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

    bind将my_addr所指的socket地址分配给未命名的sockfd文件描述符,addrlen指出该socket地址的长度。

    绑定失败时,返回-1,设置errno。

    常见errno:

    EACCES:被绑定的地址是受保护的地址。

    EADDRINUSE:被绑定的地址在使用中,如将socket绑定到一个处于TIME_WAIT状态的socket地址。

    4. 监听socket

    int listen(int sockfd, int backlog);

    sockfd指定被监听的socket。backlog提示内核监听队列的最大长度。监听队列长度超过backlog,服务器将不受理新的客户连接。典型值为5..

    5.接受连接

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

    sockfd是执行过listen系统调用的监听socket。addr参数用来获取被接受连接的远端socket地址,该socket

    地址的长度由addrlen指出。accept成功时返回一个新的连接socket,该socket唯一地标识了

    被接受的这个连接,服务器可通过读写该socket来与被接受连接的客户端通信。

    accept只是从监听队列中取出连接,而不论连接处于何种状态,更不关心任何网络状况的变化。

    6. 发起连接

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

    connect成功时返回0,一旦成功建立连接,sockfd就唯一地标识了这个连接,客户端就可以通过读写sockfd来与服务器通信。

    7.关闭连接

    int close(int fd);

    close将fd的引用计数减1,只有当fd的引用计数为0时,才真正关闭连接。多进程程序中,一次fork系统调用默认将使父进程中打开的socket的引用计数加1,

    因此我们必须在父进程和子进程中都对socket执行close调用才能将连接关闭。

    若要立即终止连接,可以使用:

    int shutdown(int sockfd, int howto);

    8. 数据读写

    TCP读写:

    ssize_t recv(int sockfd, void* buf, size_t len, int flags);

    ssize_t send(int sockfd, const void* buf, size_t len, int flags);

    recv读取sockfd上的数据,buf和len分别指定读缓冲区的位置和大小,falgs通常为0. recv成功时返回实际读取到的数据的长度。recv返回0,表示通信对方已经关闭连接。

    send往sockfd上写入数据,buf和len分别指定写缓冲区的位置和大小。send成功时返回实际写入的数据的长度。

    UDP读写:

    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);

    recvfrom 读取sockfd上的数据,buf和len参数分别指定读缓冲区的位置和大小。每次读取数据时都需要获取发送端的socket地址。

    sendto往sockfd上写入数据,buf和len分别指定写缓冲区的位置和大小。

    recvfrom和sendto系统调用也可以用于面向连接的socket数据读写,只需要把最后两个参数都设置为NULL以忽略发送端/接收端的socket地址(因为已经建立了连接)。

    通用数据读写:

    ssize_t recvmsg(int sockfd, struct msghdr* msg, int flags);

    ssize_t sendmsg(itn sockfd, struct msghdr* msg, int flags);

    可用于TCP流数据和UDP数据报。

    9. 地址信息函数

    int getsockname(int sockfd, struct sockaddr* address, socklen_t* address_len);  //获取sockfd对应的本端socket地址

    int getpeername(int sockfd, struct sockaddr* address, socklen_t* address_len);  //获取sockfd对应的远端socket地址

    通过设置socket选项SO_REUSEADDR来强制使用被处于TIME_WAIT状态的连接占用的socket地址。

  • 相关阅读:
    vue中 $event 的用法--获取当前父元素,子元素,兄弟元素
    vue的通信方式(二)---祖父孙三个级别的之间的隔代通信
    js获取当前页面url信息
    解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题
    Java POI读取excel中数值精度损失
    Java读取Excel数值内容带.0或变科学计数法的解决办法
    Java专业术语
    jdbc连接数据库
    阿里云linux配置ftp服务
    mybatis批量更新表setting parameters 错误
  • 原文地址:https://www.cnblogs.com/sssblog/p/12371965.html
Copyright © 2011-2022 走看看