linux下write操作原理、错误原因及处理方法

转载 2016年08月29日 17:22:44
linux下write操作原理、错误原因及处理方法
 
1. write函数介绍
(1)文件I/O与标准I/O之争:
      根据《UNIX环境高级编程》中介绍,文件I/O与准备I/O之间的差别主要有以下几点:其一,文件I/O是在系统的内核中实现的,而标准I/O函数则提供了文件I/O函数的一个完整的带缓冲的替代品。因此说,文件I/O是一种较低级的I/O操作函数,而标准I/O则是一种相对较高的I/O。标准I/O函数将打开的文件模型抽象成“文件流”。常见的文件I/O有:open, write, create, close, read等;标准I/O有:fopen,freopen, fdopen, getc等。第二,标准I/O一般是磁盘和终端设备I/O的首选,而当试图用于网络I/O,即对网络socket进行操作时,应该应用文件I/O。
 (2)文件I/O的阻塞与非阻塞(以write函数为例):  www.2cto.com  
      前面已经说过,文件I/O是一种带有缓冲区的操作函数,而在实际的操作过程中,势必会出现阻塞与非阻塞相关的问题。下面以write操作来介绍阻塞与非阻塞这两种情况:


 
      write函数首先将进程需要发送的数据先放在进程缓冲区中,然后向socket的发送缓冲区进行拷贝,在此,可能出现这样情况,即当进程缓冲区中的数据量大于此时发送缓冲区中所能接受的数据量时,若此时处于阻塞模式,应用进程将会被挂起,直到进程缓冲区中的数据全部拷贝到发送缓冲区中,注意此时内核也不会返回write函数,因此,在阻塞模式下,若write函数正常返回,这也并不代表数据已经完成被对方进程接收,至多只能说明数据已经被发送缓冲区完全接受;若是处于非阻塞模式,此时write操作将会失败,内核会立即返回EAGAIN错误,在此需要声明的是,有时候在某些地方说会返回EWOULDBLOCK错误,其实二者本质一样,只是分别用于不同的系统罢了,前者主要是出现于GNU系统,,而后者主要出现在类BSD系统。  www.2cto.com  
 
【引申1】阻塞与非阻塞的转换:切换socket fd的阻塞标志。
int  fcntl(int fd , int cmd)
int  fcntl(int fd,int cmd,long arg)
其中cmd代表要操作的命令,常见有:
F_GETFL:取得fd的当前状态标志
F_SETFL:设置fd的当前状态标志
[cpp]
flags = (long) fcntl(pc->fd, F_GETFL);  
bflags = flags & ~O_NONBLOCK; /* clear non-block flag, i.e. block */  
fcntl(pc->fd, F_SETFL, bflags);  
 
【引申2】Linux中发送缓存大小的查看:
sysctl -a | grep net.ipv4.tcp_wmem
net.ipv4.tcp_wmem = 4096 16384 81920 (这三个值分别代表发送缓冲区的最少字节数,默认字节数以及最多字节数)  www.2cto.com  
2. write常见错误以及原因分析:
    前面已经说过EAGAIN错误出现的原因,下面主要讲解EPIPE错误是在何种情景下产生的。
    我们知道TCP连接需要三次握手,而退出需要四个过程,而EPIPE则是产生于进程socket的退出过程中,对应上面的原理图,若B端的进程已经主动关闭(发送FIN),但是A端因为各种原因(主要是未同步),未能知晓并仍然向对方发送数据,此时A端内核会返回EPIPE错误,它会发送SIGPIPE信号给进程A,默认情况下,进程将会自动退出。
    最近在做项目过程中,因为Apache server端的keep-alive配置时间过短,导致过早发出FIN,而使得client端的socket出现EPIPE错误,最后将keep-alive时间配置稍长点,一切问题OK!

阻塞和非阻塞read/write

read函数 调用read函数从大

网络编程(24)—— linux中write和read函数的阻塞试验

刚刚接触网络编程时,很容易被客户端和服务器之间的交互搞晕,例如各种函数的阻塞和非阻塞就让人头疼。例如在我的印象中linux中用于用于对文件描述符进行读写的write()函数和read()函数是非阻塞函...

linux文件设备与I/O:read/write函数 与 阻塞 Block

一,read 函数从打开的设备或文件中读取数据 #include        ssize_t read(int fd, void *buf, size_t count);        ...

Linux下文件的阻塞与非阻塞对部分系统调用的影响

1.基本概念所谓的阻塞,即内核在对文件操作I/O系统调用时,如果条件不满足(可能需要产生I/O),则内核会将该进程挂起。非阻塞则是发现条件不满足就会立即返回。此外需要注意的是非阻塞并不是轮询,不然就和...

Unix/Linux中的read和write函数

文件描述符   对于内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符。当读或写一个文件时,使用open或cr...

Linux的write调用

linux的write调用const char *buf = "My ship is solid"; ssize_t nr;/* write the string in 'buf' to 'fd' *...

linux下与其他终端通讯 write出错

先用who命令查看所有登陆终端 #who -uH 输出如下:NAME     LINE         TIME             IDLE          PID COMMENTroot  ...

SecureCRT tftp:write error

今天用tftp下载文件时,提示tftp:write error,百思不得其解,几分钟之前还能正常下载,现在为什么不行了,后来发现是DM3730开发板的flash存储空间不够,删除掉一些无用文件就可以正...

利用tornado write_error()方法异常提醒

利用tornado write_error()方法异常提醒

linux c中write、read的用法

linux c中write、read的用法 ·write函数 1.功能 将数据写入已打开的文件内 2.相关函数 open,read,fcntl,close,lseek,sync,fsync,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux下write操作原理、错误原因及处理方法
举报原因:
原因补充:

(最多只允许输入30个字)