• socket主要函数介绍


    1.   基本套接字函数
    (1)socket函数原型

    socket(建立一个socket文件描述符)

    所需头文件

    #include <sys/types.h>       

    #include <sys/socket.h>

    函数说明

    建立一个socket文件描述符

    函数原型

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

    函数传入值

    domain

    AF_INET:IPv4协议

    AF_INET6:IPv6协议

    AF_LOCAL:Unix域协议

    AF_ROUTE:路由套接口

    AF_KEY:密钥套接口

    type

    SOCKET_STREAM:双向可靠数据流,对应TCP

    SOCKET_DGRAM:双向不可靠数据报,对应UDP

    SOCKET_RAW:提供传输层以下的协议,可以访问内部网络接口,例如接收和发送ICMP报文

    protocol

    type为SOCKET_RAW时需要设置此值说明协议类型,其他类型设置为0即可

    函数返回值

    成功:socket文件描述符

    失败:-1,失败原因存于error中

    表18-1列出了当进行socket调用时,中协议簇(domain)与类型(type)可能产生的组合。

    表18-1 socket中协议簇(domain)与类型(type)组合表

    AF_INET

    AF_INET6

    AF_LOCAL

    AF_ROUTE

    AF_KEY

    SOCK_STREAM

    TCP

    TCP

    Yes

    SOCK_DGRAM

    UDP

    UDP

    Yes

    SOCK_RAW

    IPv4

    IPv6

    Yes

    Yes

    (2)bind函数原型

    bind(将一个本地协议地址与socket文件描述符联系起来)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    将一个协议地址与socket文件描述符联系起来

    函数原型

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

    函数传入值

    sockfd

    socket文件描述符

    addr

    my_addr指向sockaddr结构,该结构中包含IP地址和端口等信息

    addrlen

    sockaddr结构的大小,可设置为sizeof(struct sockaddr)

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    利用bind函数绑定地址时,可以指定IP地址和端口号,也可以指定其中之一,甚至一个也不指定。可以使用通配地址INADDR_ANY(为宏定义,其值等于0),它通知内核选择IP地址。表18-2列出了设置socket地址结构的几种方式,但在实际中,绑定的端口号都需要指定。

             表18-2 设置socket地址结构的几种方式       

    进程指定

    说 明

    IP地址

    端口

    通配地址INADDR_ANY

    0

    内核自动选择IP地址和端口号

    通配地址INADDR_ANY

    非0

    内核自动选择IP地址,进程指定端口号

    本地IP地址

    0

    进程指定IP地址,内核自动选择端口号

    本地IP地址

    非0

    进程指定IP地址和端口号

    (3)listen函数原型

    listen (等待连接)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    等待连接

    函数原型

    int listen(int sockfd, int backlog)

    函数传入值

    sockfd

    监听socket文件描述符

    backlog

    套接字排队的最大连接个数

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    特别说明

    对于监听socket文件描述符sockfd,内核要维护两个队列,分别为未完成连接队列和已完成连接队列,这两个队列之和不超过backlog

    (4)connect函数原型

    connect(建立socket连接)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    建立socket连接

    函数原型

    int connect(int sockfd, const struct sockaddr *serv_addr,

                       socklen_t addrlen)

    函数传入值

    sockfd

    socket文件描述符

    serv_addr

    连接的网络地址和端口

    addrlen

    sockaddr结构的大小,可设置为sizeof(struct sockaddr)

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    附加说明

    函数connect激发TCP的三路握手过程,出错返回有以下几种情况:

    ①     如果客户没有收到SYN分节的响应(总共75秒,这之间可能重发了若干次SYN),则返回ETIMEDOUT

    ②     如果对客户的SYN的响应是RST,则表明该服务器主机在指定的端口上没有进程在等待与之相连,函数返回错误ECONNREFUSED

    ③     如果客户发出的SYN在中间路由器上引发一个目的地不可达的ICMP错误,内核返回EHOSTUNREACH或ENETUNREACH错误(即ICMP错误)给进程

    (5)accept函数原型

                    accept(接受socket连接)

    所需头文件

    #include <sys/types.h>     

    #include <sys/socket.h>

    函数说明

    接受socket连接,返回一个新的socket文件描述符,原socket文件描述符仍为listen函数所用,而新的socket文件描述符用来处理连接的读写操作

    函数原型

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

    函数传入参数

    sockfd: socket文件描述符

    addrlen:addr的大小,可设置为sizeof(struct sockaddr)

    函数传出参数

    addr:填入远程主机的地址数据

    函数返回值

    成功:实际读取字节数

    失败:-1,错误代码存放在error中

    附加说明

    ①     accept函数由TCP服务器调用,为阻塞函数,从已完成连接的队列中返回一个连接;如果该对列为空,则进程进入阻塞等待

    ②     函数返回的套接字为已连接套接字,而监听套接字仍为listen函数所用

    (6)close函数原型

    close (关闭连接的socket文件描述符)

    所需头文件

    #include <unistd.h>

    函数说明

    关闭连接的socket文件描述符

    函数原型

    int close(int sockfd)

    函数传入值

    sockfd:socket文件描述符

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    附加说明

    ①     close函数默认功能是将套接字置为“已关闭”标记,并立即返回给进程,这个套接字不能再为该进程所用

    ②     正常情况下,close将引发四个分节终止序列,但在终止前将发送已排队的数据

    ③     如果套接字描述符访问计数在调用close后大于0(多个进程共享同一个套接字的情况下),则不会引发TCP终止序列(即不会发送FIN分节)

    (7)shutdown函数原型

    shutdown(终止socket通信)

    所需头文件

    #include <sys/socket.h>

    函数说明

    终止socket通信

    函数原型

    int shutdown(int s, int how)

    函数传入值

    s

    socket文件描述符

    how

    0(SHUT_RD):关闭socket连接的读这一半,不再接收套接字中的数据且现留在收缓冲区的数据作废

    1(SHUT_WR):关闭socket连接的写这一半(半关闭),但留在套接字发送缓冲区中的数据都会被发送,后跟TCP连接终止序列,不管访问计数是否大于0,此后将不能再执行对套接字的任何写操作

    2(SHUT_RDWR):socket连接的读、写都关闭

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    (8)read函数原型

                    read(从打开的socket文件流中读取数据)

    所需头文件

    #include <unistd.h>

    函数说明

    从打开的socket文件流中读取数据,这里仅说明此函数应用于socket的情况

    函数原型

    ssize_t read(int fd, void *buf ,size_t count)

    函数传入参数

    fd: socket文件描述符

    count:最大读取字节数

    函数传出参数

    buf:读取数据的首地址

    函数返回值

    成功:实际读取字节数

    失败:-1,错误代码存放在error中

    附加说明

    调用函数read从socket文件流中读取数据时,有如下几种情况:

    ①     套接字接收缓冲区接收数据,返回接收到的字节数

    ②     TCP协议收到FIN数据,返回0

    ③     TCP协议收到RST数据,返回-1,同时errno设置为ECONNRESET

    ④     进程阻塞过程中接收到信号,返回-1,同时errno设置为EINTR

    (9)write函数原型

                     write(向socket文件流中写入数据)

    所需头文件

    #include <unistd.h>

    函数说明

    向socket文件流中写入数据,这里仅说明此函数应用于socket的情况

    函数原型

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

    函数传入参数

    fd: socket文件描述符

    buf:写入数据的首地址

    count:最大写入字节数

    函数返回值

    成功:实际写入的字节数

    失败:-1,错误代码存放在error中

    附加说明

    调用函数write向socket文件流写数据时,有如下几种情况:

    ①        套接字发送缓冲区有足够空间,返回发送的字节数

    ②        TCP协议接收到RST数据,返回-1,同时errno设置为ECONNRESET

    ③        进程阻塞过程中接收到信号,返回-1,同时errno设置为EINTR

    2.   高级套接字函数
    recv和send函数提供了和read和write差不多的功能。不过它们提供了第四个参数来控制读写操作。

    (1) send函数原型

    send(通过socket文件描述符发送数据到对方)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    通过socket文件描述符发送数据到对方

    函数原型

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

    函数传入值

    s

    socket文件描述符

    buf

    发送数据的首地址

    len

    发送数据的长度

    flags

    0:此时功能同write,flags还可以设为以下标志的组合

    MSG_OOB:发送带外数据

    MSG_DONTROUTE:告诉IP协议,目的主机在本地网络,没有必要查找路由表

    MSG_DONTWAIT:设置为非阻塞操作

    MSG_NOSIGNAL:表示发送动作不愿被SIGPIPE信号中断

    函数返回值

    成功:实际发送的字节数

    失败:-1,失败原因存于error中

    (2) recv函数原型

    recv(通过socket文件描述符从对方接收数据)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    通过socket文件描述符从对方接收数据

    函数原型

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

    函数传入值

    s

    socket文件描述符

    len

    可接收数据的最大长度

    flags

    0:此时功能同read,flags还可以设为以下标志的组合

    MSG_OOB:接收带外数据

    MSG_PEEK:查看数据标志,返回的数据并不在系统中删除,如果再次调用recv函数会返回相同的数据内容

    MSG_DONTWAIT:设置为非阻塞操作

    MSG_WAITALL:强迫接收到len大小的数据后才返回,除非有错误或有信号产生

    函数传出值

    buf

    接收数据的首地址

    函数返回值

    成功:实际发送的字节数

    失败:-1,失败原因存于error中

    3.   套接字属性控制函数
    系统提供getsockopt、setsockopt两函数获取和修改套接字结构中一些属性,通过修改这些属性,可以调整套接字的性能,进而调整应用程序的性能。

    (1) getsockopt函数原型

    getsockopt(获取套接字的属性)

    所需头文件

    #include <sys/types.h>   

    #include <sys/socket.h>

    函数说明

    获取套接字的属性

    函数原型

    int getsockopt(int s, int level, int optname,

                          void *optval, socklen_t *optlen)

    函数传入值

    s

    socket文件描述符

    level

    SOL_SOCKET:通用套接字选项

    IPPROTO_IP:IP选项

    IPPROTO_TCP:TCP选项

    optname

    访问的选项名,具体见表18-3

    optlen

    optval的长度

    函数传出值

    optval

    取得的属性值

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    表18-3 套接字属性表

    level(级别)

    optname(选项名

    说明

    数据类型

    SOL_SOCKET

    SO_BROADCAST

    允许发送广播数据

    int

    SO_DEBUG

    允许调试

    int

    SO_DONTROUTE

    不查找路由

    int

    SO_ERROR

    获得套接字错误

    int

    SO_KEEPALIVE

    保持连接

    int

    SO_LINGER

    延迟关闭连接

    struct linger

    SO_OOBINLINE

    带外数据放入正常数据流

    int

    SO_RCVBUF

    接收缓冲区大小

    int

    SO_SNDBUF

    发送缓冲区大小

    int

    SO_RCVLOWAT

    接收缓冲区下限

    int

    SO_SNDLOWAT

    发送缓冲区下限

    int

    SO_RCVTIMEO

    接收超时

    struct timeval

    SO_SNDTIMEO

    发送超时

    struct timeval

    SO_REUSERADDR

    允许重用本地地址和端口

    int

    SO_TYPE

    获得套接字类型

    int

    SO_BSDCOMPAT

    与BSD系统兼容

    int

    IPPROTO_IP

    IP_HDRINCL

    在数据包中包含IP首部

    int

    IP_OPTINOS

    IP首部选项

    int

    IP_TOS

    服务类型

    int

    IP_TTL

    生存时间

    int

    IPPRO_TCP

    TCP_MAXSEG

    TCP最大数据段的大小

    int

    CP_NODELAY

    不使用Nagle算法

    int

    (2)setsockopt函数原型

    setsockopt(设置套接字的属性)

    所需头文件

    #include <sys/types.h>   

    #include <sys/socket.h>

    函数说明

    设置套接字的属性

    函数原型

    int setsockopt(int s, int level, int optname,

                          const void *optval, socklen_t optlen)

    函数传入值

    s

    socket文件描述符

    level

    SOL_SOCKET:通用套接字选项

    IPPROTO_IP:IP选项

    IPPROTO_TCP:TCP选项

    optname

    设置的选项名,具体见表18-3

    optval

    设置的属性值

    optlen

    optval的长度

    函数返回值

    成功:0

    失败:-1,失败原因存于error中

    (3)getsockopt、setsockopt函数举例

    sockopt.c源代码如下:

    #include <stdio.h>

    #include <sys/types.h>

    #include <sys/socket.h>

    int main()

    {

        int sockfd,optval,optlen = sizeof(int);

        int sndbuf = 0 ;

        int rcvbuf = 0 ;

        int flag;

        if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)

        {

            perror("socket") ;

            return -1 ;

        }

        getsockopt(sockfd,SOL_SOCKET,SO_TYPE,&optval,&optlen);

        printf("optval = %d ",optval);

        optlen = sizeof(sndbuf);

        flag = getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf,&optlen);

        printf("sndbuf=%d ",sndbuf) ;

        printf("flag=%d ",flag) ;

        sndbuf = 51200;   

        flag = setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf, optlen);

        sndbuf=0 ;

        flag = getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,&sndbuf,&optlen);

        printf("sndbuf=%d ",sndbuf) ;

        printf("flag=%d ",flag) ;

        close(sockfd);

        return 0 ;

    }

    编译 gcc sockopt.c -o sockopt。

    执行 ./sockopt, 执行结果如下:

    optval = 1

    sndbuf=16384

    flag=0

    sndbuf=102400

    flag=0

    4.   UDP读写函数
    UDP套接字是无连接协议,必须使用sendto函数发送数据,必须使用recvfrom函数接收数据,发送时需指明目的地址。sendto函数与send功能基本相同,recvfrom与recv功能基本相同,只不过sendto函数和recvfrom函数参数中都带有对方地址信息,这两个函数是专门为UDP协议提供的。

    (1)sendto函数原型

    sendto(通过socket文件描述符发送数据到对方)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    通过socket文件描述符发送数据到对方,用于UDP协议

    函数原型

    ssize_t sendto(int s, const void *buf, size_t len, int flags,

                          const struct sockaddr *to, socklen_t tolen)

    函数传入值

    s

    socket文件描述符

    buf

    发送数据的首地址

    len

    发送数据的长度

    flags

    0:默认方式发送数据,flags还可以设为以下标志的组合

    MSG_OOB:发送带外数据

    MSG_DONTROUTE:告诉IP协议,目的主机在本地网络,没有必要查找路由表

    MSG_DONTWAIT:设置为非阻塞操作

    MSG_NOSIGNAL:表示发送动作不愿被SIGPIPE信号中断

    to

    存放目的主机IP地址和端口信息

    tolen

    to的长度,可设置为sizeof(struct sockaddr)

    函数返回值

    成功:实际发送的字节数

    失败:-1,失败原因存于error中

    (2) recvfrom函数

    recv(通过socket文件描述符从对方接收数据)

    所需头文件

    #include <sys/types.h>

    #include <sys/socket.h>

    函数说明

    通过socket文件描述符从对方接收数据,用于UDP协议

    函数原型

    ssize_t recvfrom(int s, void *buf, size_t len, int flags,

                            struct sockaddr *from, socklen_t *fromlen)

    函数传入值

    s

    socket文件描述符

    len

    可接收数据的最大长度

    flags

    0:默认方式接收数据,flags还可以设为以下标志的组合

    MSG_OOB:接收带外数据

    MSG_PEEK:查看数据标志,返回的数据并不在系统中删除,如果再次调用recv函数会返回相同的数据内容

    MSG_DONTWAIT:设置为非阻塞操作

    MSG_WAITALL:强迫接收到len大小的数据后才返回,除非有错误或有信号产生

    fromlen

    from的长度,可设置为sizeof(struct sockaddr)

    函数传出值

    buf

    接收数据的首地址

    from

    存放发送方的IP地址和端口

    函数返回值

    成功:实际发送的字节数

    失败:-1,失败原因存于error中
    --------------------- 

  • 相关阅读:
    Summary for sql join in Oracle DB
    Merge data into table in Oracle
    PLSQL存储过程传出大量异常错误信息
    oracle 11g plsql解析json数据示例
    识别'低效执行'的SQL语句
    如何开启MySQL 5.7.12 的二进制日志
    Linux下ps命令详解 Linux下ps命令的详细使用方法
    Linux(Unix)时钟同步ntpd服务配置方法
    MySQL 常用命令总结
    MySQL 数据库通过日志恢复
  • 原文地址:https://www.cnblogs.com/ly570/p/10947712.html
Copyright © 2020-2023  润新知