美文网首页
Linux-IO函数

Linux-IO函数

作者: VD2012 | 来源:发表于2017-12-11 21:53 被阅读0次

    数据的IO和复用

    网络数据能够正常的到达用户,并被用户接受网络数据传输的目的。网络数据的接受以及发送有多种方案,例如直接接受或者发送数据通过向量发送接受数据,通过消息进行接受以及发送。

    1.介绍主要的常用的IO函数

    2。介绍几种常用的IO模型

    3 介绍select和pselect函数,如何利用这两个文件的描述符号进行文件读写描述符的监视。

    4.简单的介绍函数poll和ppoll含义使用以及区别

    5 以简单的例子介绍非堵塞编程。

    --------------------------------------------------     IO 函数    -----------------------------------------------

    recv函数用于接受数据,函数的原型如下。recv函数从套接字s中接受数据放到缓冲区buf中,buf的长度为len,操作的方式由flag决定。第一个参数s是套接字文件的描述符,它是由函数socket()返回的,第二个参数buf是一个指针,指向接受网络套接字的缓冲区,第三个参数表示缓冲区的大小,以字节为单位。


    #include <sys/type.h>

    #include <sys/socket.h>

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

                                               flags的值以及含义

    MSG_DONTWAIT                    非阻赛的操作,立刻返回不等待

    MSG_ERRQUEUE                   错误消息从套接字错误队列接收

    MSG_OOB                                接收外数据数据

    MSG_PEEK                               查看数据,不进行数据缓冲区的清空

    MSG_TRUNC                             返回所有的数据,及时指定缓冲区过小

    MSG_WAITALL                          等待所有的消息

    MSG_DONTWAIT:这个标志将单个IO操作设为非堵塞方式,而不需要在套接字上打开非堵塞的标志,执行IO操作。然后关闭非堵塞的标志。

    MSG_ERRQUEUE:  改错误的传输依赖于所使用的协议。

    MSG_OOB :这个标志可以接收带外数据,而不接收一般的数据。

    MSG_PEEK : 这个标志用于查看可读数据,在recv函数执行后,内核不会将这些数据丢弃掉。

    MSG_TRUNC: 在接收数据后,如果用户的缓冲区大小不足以完全复制缓冲区的数据,则将数据折断,仅复制用户缓冲区大小的数据,多余的数据将会舍弃掉。

    MSG_WAITALL:这个标志告诉内核在没有读到请求的字节数之前不使读操作返回。如果系统支持使用这个标志,可以去掉readn()函数而使用下面的代替

    #define readn(fd,ptr,n) recv(fd,ptr,n,MSG_WAITALL)

    即使设置MSG_WAITALL,如果发生以下情况(a)捕获一个信号(b)连接终止(c)在套接字上发生了错误,这个函数返回的字节数依然会比请求的少。当指定MSG_WAITALL标志时,函数会复制与用户指定长度相等的数据。如果内核中的当前数据不能满足要求,会一直等待直到数据足够才返回。

    函数recv()的返回值是成功接收到的字节数。当返回-1时错误发生,可以查看errno获取错误码,当另一个访民啊使用close()关闭连接时,返回值为0;

    常见的错误码如下:

    EAGAIN          套接字定义为非堵塞,而操作采用了堵塞的方式,或者定义的超时时间已经达到却没有接收到数据。

    EBADF   参数s不是合法的描述符

    ECONNREFUSED  远程主机不允许此操作

    EFAULT  接受缓冲区指针在此进程之外

    EINTR      接收到中断信号

    EINTVAl   传递了不合法的参数

    ENOTCONN   套接字s表示流式套接字,此套接字没有连接。

    ENOTSOCK   参数不是套接字描述符

    recv()函数通常用于TCP类型的套接字。UDP使用recvfrom()函数接受数据,当然在数据包套接字绑定地址一节端口号后,也可以使用recv()接受数据。

    recv()函数 从内核的接收缓冲区复制到数据到用户指定的缓冲区。当内核的缓冲区比指定的缓冲区小时,一般情况下(没有采用MSG_WAITALL标志)会复制缓冲区的所有的数据到用户缓存区。并返回数据的长度。当内核的接收的缓冲区的数据比用户指定的多时,会将用户指定长度的len的接收缓冲区的数据复制到用户指定地址。其余的数据需要下次调用该函数时在复制,内核在复制用户指定的数据之后,会销毁已经复制完毕的数据,并进行调整。

    使用send()函数发送数据

    send()函数用于发送数据,函数的原型如下

    #include<sys/types.h>

    #include <sys/socket.h>

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

    send()函数将缓冲区buf大小为len的数据。通过套接字文件描述符按照flags指定的方式发送出去,其中的参数含义与recv中的含义一致,它的返回值是成功的字节数,用于用户的缓冲区buf中的数据在通过send()函数进行发送的时候,并不一定能够全部发送出去,所以要检查send() 函数的返回值,按照与计划发送的字节长度是否相等来判断下一步的操作。

    当send()函数的返回值小于len的时候,表明缓冲区仍然由部分数据没有成功的发送,这时需要重新发送剩余的部分,通常剩余数据发送的方法是对原来的buf中的数据位置进行偏移,偏移的大小为已经成功发送的字节数。

    send 函数错误吗如下:

    函数send()只能用于套接字处于连接状态的描述符,之前必须使用connect()函数或者其它函数进行连接。对于send()函数和write()函数之间的差别表示发送方式的flag,当flag为0时,send()函数和write()函数完全一致,而且send(s,buf,len,flags)与sendto(s,buf,len,flags,NULL,0)等价的。

    相关文章

      网友评论

          本文标题:Linux-IO函数

          本文链接:https://www.haomeiwen.com/subject/cquwixtx.html