导航:首页 > 操作系统 > android非阻塞socket

android非阻塞socket

发布时间:2025-02-05 12:06:32

① socket阻塞和非阻塞的区别

阻塞socket和非阻塞socket的区别:
1、读操作
对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返回。当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数。当sockt的接收缓冲区中的数据大于期望读取的字节数时,读取期望读取的字节数,返回实际读取的长度。
对于非阻塞socket而言,socket的接收缓冲区中有没有数据,read调用都会立刻返回。接收缓冲区中有数据时,与阻塞socket有数据的情况是一样的,如果接收缓冲区中没有数据,则返回错误号为EWOULDBLOCK,表示该操作本来应该阻塞的,但是由于本socket为非阻塞的socket,因此立刻返回,遇到这样的情况,可以在下次接着去尝试读取。如果返回值是其它负值,则表明读取错误。
2、写操作
对于写操作write,原理是类似的,非阻塞socket在发送缓冲区没有空间时会直接返回错误号EWOULDBLOCK,表示没有空间可写数据,如果错误号是别的值,则表明发送失败。如果发送缓冲区中有足够空间或者是不足以拷贝所有待发送数据的空间的话,则拷贝前面N个能够容纳的数据,返回实际拷贝的字节数。
而对于阻塞Socket而言,如果发送缓冲区没有空间或者空间不足的话,write操作会直接阻塞住,如果有足够空间,则拷贝所有数据到发送缓冲区,然后返回.
3、建立连接
阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.
非阻塞方式,connect将启用TCP协议的三次握手,但是connect函数并不等待连接建立好才返回,而是立即返回。返回的错误码为EINPROGRESS,表示正在进行某种过程.

4、接收
连接
对于阻塞方式的倾听socket,accept在连接队列中没有建立好的连接时将阻塞,直到有可用的连接,才返回。

非阻塞倾听socket,在有没有连接时都立即返回,没有连接时,返回的错误码为EWOULDBLOCK,表示本来应该阻塞

② 非阻塞方式socket send()返回大小和实际发送大小不一致

非阻塞模式是立即返回的,无法保证一次把包发完,所以发送时最好判断发送字节的多少,如果没有发送完成,继续调用发送接口发送

③ 服务器编程心得(四)—— 如何将socket设置为非阻塞模式

在服务器编程中,设置socket为非阻塞模式是提高性能的关键技术之一。不同操作系统上实现这一功能的方法有所差异。在Windows平台上,无论是使用socket()函数还是WSASocket()函数创建的socket都是默认为阻塞模式的。

相比之下,Linux平台上在使用socket()函数创建socket时,可以通过在type参数中设置SOCK_NONBLOCK标志来创建一个非阻塞模式的socket。例如:

在Linux上,通过将SOCK_NONBLOCK标志设置为SOCK_NONBLOCK,即可创建一个非阻塞模式的socket。

在Windows和Linux平台上的accept()函数返回的socket同样是阻塞模式的,不过Linux额外提供了一个accept4()函数,该函数可以直接将返回的socket设置为非阻塞模式。实现方法只需将accept4()函数的最后一个参数flags设置为SOCK_NONBLOCK即可。

除了在创建socket时设置非阻塞模式外,还可以通过调用特定的API函数来实现。在Linux平台上,可以使用fcntl()或者ioctl()函数来修改socket的阻塞属性。例如:

通过调用fcntl()函数或者ioctl()函数,即可将Linux平台上的socket设置为非阻塞模式。在设置非阻塞模式时,需要确保在接收和发送数据时使用了MSG_DONTWAIT标志,即在recv、recvfrom和send、sendto函数调用时,将flag参数设置为MSG_DONTWAIT。然而,根据Linux手册的说明,设置recv()函数的flags标识位为MSG_DONTWAIT或者通过fcntl()函数设置O_NONBLOCK标识,已经足够实现非阻塞操作,无需同时设定两种方式。

在Windows平台上,可以通过调用ioctlsocket函数来改变socket的阻塞模式。将cmd参数设置为FIONBIO,同时将*argp参数设置为0或非0,即可分别设置socket为阻塞模式或非阻塞模式。需要注意的是,如果对socket调用了WSAAsyncSelect()或WSAEventSelect()函数后,再尝试使用ioctlsocket()将socket设置为非阻塞模式,将会失败。解决此问题,需要先通过设置lEvent参数为0或设置lNetworkEvents参数为0来禁用WSAAsyncSelect()或WSAEventSelect(),然后再调用ioctlsocket()设置socket为阻塞模式。

在实际项目中,有的前辈可能会在一个循环里调用fcntl()或者ioctlsocket()函数来改变socket的阻塞模式。然而,这是否必要,仍有待验证。建议读者根据实际需求和项目要求选择合适的方法。

如果想系统地学习上述知识,推荐阅读尹圣雨的《TCP/IP 网络编程》这本书,它兼顾了Windows和Linux两个平台,使用C语言和操作系统的Socket API,能够帮助读者理解网络编程的基本概念和实现方法。对于更深入的高性能网络框架和设计,可以参考游双老师的《Linux 高性能服务器编程》一书。

此外,作者也出版了一本书《C++服务器开发精髓》,涵盖了从客户端到服务器、从Windows到Linux的经验总结,包括C++开发编译调试技术、多线程编程、网络故障排查、通信协议设计、高性能网络框架设计、服务框架设计、服务组件开发等知识。获取更多书籍信息,请参考相关链接。

阅读全文

与android非阻塞socket相关的资料

热点内容
阿里云服务器远程链接不成功 浏览:482
文件系统pdf 浏览:762
原神安卓区服什么意思 浏览:34
贝壳app怎么线上发布 浏览:157
如何挑选安卓系统机顶盒 浏览:53
安卓快充使用有什么注意事项 浏览:909
黑马程序员的云计算网课 浏览:946
endnotestyle文件夹怎么导入 浏览:460
讲解少儿编程演讲会开头 浏览:424
思科交换机基础命令 浏览:497
便签可以设置加密吗 浏览:339
免费漫画app怎么看书 浏览:27
华为笔记本电脑怎么安装抖音app 浏览:412
阿里云国际版试用的服务器怎么搞 浏览:895
java正则表达式工具 浏览:160
oa服务器怎么设置ftp 浏览:10
安卓如何安装obb 浏览:442
QQ聊天记录journal文件夹 浏览:118
苹果公司云服务器地址 浏览:85
加密记事本手机 浏览:437