Linux-IO函数

数据的IO和复用

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

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

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

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

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

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

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

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



#include

#include

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

#include

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函数)