在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP socket相关的总结, 可能会存在错误, 有任何问题欢迎大家提出.
对于网络编程的更多详细说明建议参考下面的书籍
《UNIX网络编程》 《TCP/IP 详解》 《Unix环境高级编程》
非阻塞IO和阻塞IO:
在网络编程中对于一个网络句柄会遇到阻塞IO和非阻塞IO的概念, 这里对于这两种socket先做一下说明
基本概念:socket的阻塞模式意味着必须要做完IO操作(包括错误)才会返回。 非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。
设置:
一般对于一个socket是阻塞模式还是非阻塞模式有两种方式 fcntl设置和recv,send系列的参数.
fcntl函数可以将一个socket句柄设置成非阻塞模式:
flags = fcntl(sockfd, F_GETFL, 0); fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); 设置之后每次的对于sockfd的操作都是非阻塞的
recv, send函数的最后有一个flag参数可以设置成MSG_DONTWAIT临时将sockfd设置为非阻塞模式,而无论原有是阻塞还是非阻塞。 recv(sockfd, buff, buff_size, MSG_DONTWAIT); send(scokfd, buff, buff_size, MSG_DONTWAIT);
区别:
读:
读本质来说其实不能是读,在实际中, 具体的接收数据不是由这些调用来进行,是由于系统底层自动完成的,read也好,recv也好只负责把数据从底层缓冲copy到我们指定的位置. 对于读来说(read, 或者 recv) ,在阻塞条件下如果没有发现数据在网络缓冲中会一直等待,当发现有数据的时候会把数据读到用户指定的缓冲区,但是如果这个时候读到的数据量比较少,比参数中指定的长度要小,read并不会一直等待下去,而是立刻返回。read的原则是数据在不超过指定的长度的时候有多少读多少,没有数据就会一直等待。所以一般情况下我们读取数据都需要采用循环读的方式读取数据,一次read完毕不能保证读到我们需要长度的数据,read完一次需要判断读到的数据长度再决定是否还需要再次读取。在非阻塞的情况下,read的行为是如果发现没有数据就直接返回,如果发现有数据那么也是采用有多少读多少的进行处理.对于读而言,阻塞和非阻塞的区别在于没有数据到达的时候是否立刻返回.
recv中有一个MSG_WAITALL的参数 recv(sockfd, buff, buff_size, MSG_WAITALL), 在正常情况下 recv是会等待直到读取到buff_size长度的数据,但是这里的WAITALL也只是尽量读全,在有中断的情况下recv还是可能会被打断,造成没有读完指定的buff_size的长度。所以即使是采用recv + WAITALL参数还是要考虑是否需要循环读取的问题,在实验中对于多数情况下recv还是可以读完buff_size,所以相应的性能会比直接read进行循环读要好一些。不过要注意的是这个时候的sockfd必须是处于阻塞模式下,否则WAITALL不能起作用。
写:
写的本质也不是进行发送操作,而是把用户态的数据copy到系统底层去,然后再由系统进行发送操作,返回成功只表示数据已经copy到底层缓冲,而不表示数据以及发出,更不能表示对端已经接收到数据.
对于write(或者send)而言,在阻塞的情况是会一直等待直到write完全部的数据再返回.这点行为上与读操作有所不同,究其原因主要是读数据的时候我们并不知道对端到底有没有数据,数据是在什么时候结束发送的,如果一直等待就可能会造成死循环,所以并没有去进行这方面的处理;而对于write, 由于需要写的长度是已知的,所以可以一直再写,直到写完.不过问题是write是可能被打断造成write一次只write一部分数据, 所以write的过程还是需要考虑循环write, 只不过多数情况下一次write调用就可能成功.. C3 _) ?- V9 c$ z) k: ~" I
非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写操作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write到一部分的情况.
转载声明: 本文转自http://bbs.51cto.com/viewthread.php?tid=723850&page=
分享到:
相关推荐
python程序员面试常见问题汇总。包含:基础知识、爬虫、正则表达式、网络编程、Flask、Django。 例如: 1、基础篇:python的优缺点、深拷贝和浅拷贝之间的区别是什么、列表和元组之间的区别等; 2、进阶篇:python中...
1.网络编程概要.mkv2.一个TCP的简单实验.mkv3.课程内容大纲.mkv4.回顾基础的Sockets API.mkv5.TTCP代码概览.mkv6.使用TTCP进行网络传输性能测试.mkv7.阻塞IO下的TTCP实验.mkv8.TCP自连接.mkv9.扩展练习.mkv10.时钟...
前端开发常见问题涵盖了多个维度,从技术基础知识、编码实践、性能优化到跨平台兼容性等。以下是一些主要的前端开发常见问题及其简要说明: 基础知识不牢固 编程思维和基本算法的理解:新手开发者可能会因为对基础...
本文档对Linux 网络编程中socket系列函数报的错误码及其常见处理总结
本书的作者都是第一线的网络游戏开发人员,书中的所有内容都整理自完整的网络游戏项目,是实践经验的总结。第二章到第十四章的内容,基本是从一个多人在线冒险型网络游戏项目中整理而来,第十五章则整理于一个即时...
本书主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服 务程序的主流常规技术, 这也是我对过去5年...地开发各类常见的服务端网络应用程序。 本书以muduo网络库为例, 讲 解这种编程模型的使用方法及注意事项
学习笔记:在学习过程中,我们整理了丰富的学习笔记,这些笔记包含了重点知识点的总结、实战经验分享以及常见问题的解答。通过阅读这些笔记,你可以随时巩固所学,解决学习中遇到的问题,提高学习效率。 项目实战:...
│ ├── 实战:常用工具、常见问题汇总 ├── 03_数学基础(程序员必备数学知识) ├── 04_算法原理(传统算法,优化算法,遗传算法) ├── 05_机器学习(资源+原理+实战) ├── 06_深度学习(资源+原理+...
python 基础面试常见汇总,本人经历整理所得。适合提升基础知识的群体参考。 包含各种概念、算法(含有源代码),还有部分从网络上搜集整理所得。 其它资源参考:https://liuzheng520.blog.csdn.net/ Python由荷兰...
几乎包含了面试中经常出现的C++问题, 并且有详尽的解答, 是学习C++, 和准备C++面试的非常好的材料。。
采用Python这一简洁易用的编程语言,从基础到进阶,逐步讲解了每章的课后编程题的实现和讲解,以及Python语言的基本语法、数据结构、网络编程、协议分析等知识点,以及一些常见的编程问题和技巧。本资源利用谢希仁...
本教程包含了100个常见的Python面试题,涵盖Python基础知识、高级特性、网络编程、数据库操作、数据结构和算法等多个方面。每个问题都提供了详细的解析,帮助面试者更好地准备Python面试。 适用人群: 本教程适合...
文档里有自己总结计算机网络l常见面试题,自己凭借这套面试题拿下5-10个offer,目前已入职北京某互联网大厂,适合于正在找工作的同学。
11.1 对汇总、细节以及综合这二者的报表建立同一报表 305 11.2 用按窗体查询来创建同一报表的动态分组 312 11.3 复杂的特征:创建迂回报表 316 11.3.1 查看前面的报表 318 11.3.2 "列”页面的属性 318 ...
本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的...
作者借助于如今黑客社区中备受青睐的编程语言Python引领读者构建出精悍的脚本程序来一一应对上述这些问题。出现在本书中的相当一部分Python代码实例借鉴或直接来源于一些优秀的开源安全项目,诸如Pedram Amini的...
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...
13.1.1 Windows网络架构总结 436 13.1.2 NDIS中间层驱动简介 437 13.1.3 NDIS中间层驱动的应用 438 13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态...
13.1.1 Windows网络架构总结 436 13.1.2 NDIS中间层驱动简介 437 13.1.3 NDIS中间层驱动的应用 438 13.1.4 NDIS包描述符结构深究 439 13.2 中间层驱动的入口与绑定 442 13.2.1 中间层驱动的入口函数 442 13.2.2 动态...
计算机网络安全总结 网络安全技术复习 网络安全基础知识 网络安全的定义:安全就是最大限度地减少数据和资源被攻击的可能性。 1、 网络安全包括四个方面:物理安全、 数据安全、软件安全、安全管理。 2、 网络安全的...