网络编程 write 阻塞和非阻塞下的区别

网络编程 write 阻塞和非阻塞下的区别

1,write原型,参数及返回值。

#include

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

------函数write 只是将用户进程中的数据拷贝到内核缓冲区中,拷贝数据的大小取决于内核缓冲区的大小与nbytes。

参数:

fd:标示某个套接字;

buf:进程中需要往对端发送的数据;

nbytes:需要发送的数据长度。

返回值:

-1:相应的错误码会写到error中。

error :EAGAIN 或 EWOULDBLOCK,表示缓冲区已满,此时无法写入,需要等待下次机会。(EAGAIN和EWOULDBLOCK 两者本质一样,只是分别用于不同的系统,前者是gnu,即linux,后者是bsd系统,都表示缓冲区已满,无空间可写)

error:EPIPE,这是一种典型的错误场景,当client A 已经关闭了,server B 由于网络延迟等原因未察觉,依然向这个已关闭的fd,执行write时,内核会向B 返回 EPIPE错误码,并产生SIGPIPE,默认情况下,进程对该信号的动作是自动退出,所以一般服务器需要处理该信号。

>0:写入内核缓冲区的数据大小。

=0:返回一般不会为0,根据第3个参数的值,如果为0,则表示啥都不执行,write返回0。

2,write 在阻塞和非阻塞下的区别。

阻塞下 当内核缓冲区大小不足以容纳需要写入的 nbytes,write一直阻塞等待,直到缓冲区大小 >= nbytes 时,write一次性copy,等待的过程中,有可能会被信号中断。

当内核缓冲区大小能够容纳需要写入的nbytes,write copy到缓冲区,并返回 nbytes。

非阻塞 坚持的原则是有多少写多少,如果内核缓冲区空间足够,同阻塞情况,一次性copy;如果缓冲区不够,则缓冲区的大小是有多少就写入多少,并返回该值,显然返回值小于nbytes,此种情况需要循环的方式将nbytes数据写到缓冲区;如果缓冲区是满的,则返回-1,并置error值为EAGAIN 或 EWOULDBLOCK。

3,write 的循环写入。

int nwrite(int fd, char *buf, int nbytes)

{

int len = 0;

char *ptr = buf;

int left = nbytes;

while(left)

{

len = write(fd, ptr, left);

if(len < 0)

{

if(error == EAGAIN)

len = 0;

else

return -1; //真正的错误

}

if(len == 0)

{

break;

}

left -= len;

ptr += len;

}

return nbytes;

}

4,write 遗留几个问题?

write非阻塞的时候需要检测中断吗?

write一次性能最大写入缓冲区多少字节?

5,总结

write阻塞下非阻塞缓冲区满一直等待返回-1,并置error为EAGAIN有缓冲区,但不够指定写的大小一直等待,直到有足够空间写入一部分,并返回该写入的部分大小有缓冲区,而且大小也够一次性写入一次性写入

相关尊享内容

凰权弈天下一共多少集
365bet游戏下载

凰权弈天下一共多少集

📅 07-19 👑 707
比亚迪S6轮胎价格是多少
365bet游戏下载

比亚迪S6轮胎价格是多少

📅 08-15 👑 489
【2025最新】八大外汇返佣平台全面比较,业内最高返佣推荐!
365app下载安装官方免费下载

【2025最新】八大外汇返佣平台全面比较,业内最高返佣推荐!

📅 07-22 👑 673
iPhone 6s什么时候上市?iPhone 6s上市时间
365app下载安装官方免费下载

iPhone 6s什么时候上市?iPhone 6s上市时间

📅 08-20 👑 324