精华内容
下载资源
问答
  • C++编程中内存溢出问题

    千次阅读 2015-11-02 18:02:06
    转载自另一篇博客:... 1. 良好的编程习惯是预防内存漏洞的根本 2.  正确申请和释放内存空间。 3.  记得在每个可能的出口检查指针 一、为什么会出现内存溢出问题? 导致内存溢出问题的原因有

    转载自另一篇博客:http://blog.chinaunix.net/uid-8318378-id-2032222.html

    1.        良好的编程习惯是预防内存漏洞的根本

    2.      正确申请和释放内存空间。

    3.      记得在每个可能的出口检查指针

    一、为什么会出现内存溢出问题?

    导致内存溢出问题的原因有很多,比如:

    (1) 使用非类型安全(non-type-safe)的语言如 C/C++等。

    (2) 以不可靠的方式存取或者复制内存缓冲区。

    (3) 编译器设置的内存缓冲区太靠近关键数据结构。

    下面来分析这些因素:

    1. 内存溢出问题是 C语言或者 C++ 语言所固有的缺陷,它们既不检查数组边界,又不检查类型可靠性(type-safety)。众所周知,用 C/C++语言开发的程序由于目标代码非常接近机器内核,因而能够直接访问内存和寄存器,这种特性大大提升了 C/C++语言代码的性能。只要合理编码,C/C++应用程序在执行效率上必然优于其它高级语言。然而,C/C++语言导致内存溢出问题的可能性也要大许多。其他语言也存在内容溢出问题,但它往往不是程序员的失误,而是应用程序的运行时环境出错所致。

    2. 当应用程序读取用户(也可能是恶意攻击者)数据,试图复制到应用程序开辟的内存缓冲区中,却无法保证缓冲区的空间足够时(换言之,假设代码申请了 N 字节大小的内存缓冲区,随后又向其中复制超过 N字节的数据)。内存缓冲区就可能会溢出。想一想,如果你向 12盎司的玻璃杯中倒入 16盎司水,那么多出来的 4盎司水怎么办?当然会满到玻璃杯外面了!

    3. 最重要的是,C/C++编译器开辟的内存缓冲区常常邻近重要的数据结构。现在假设某个函数的堆栈紧接在在内存缓冲区后面时,其中保存的函数返回地址就会与内存缓冲区相邻。此时,恶意攻击者就可以向内存缓冲区复制大量数据,从而使得内存缓冲区溢出并覆盖原先保存于堆栈中的函数返回地址。这样,函数的返回地址就被攻击者换成了他指定的数值;一旦函数调用完毕,就会继续执行函数返回地址处的代码。非但如此,C++的某些其它数据结构,比如 v-table、例外事件处理程序、函数指针等,也可能受到类似的攻击。

    二、解决内存溢出问题

    不要太悲观,下面讨论内存溢出问题的解决和预防措施。

    1、改用受控代码

    2、遵守黄金规则

    当你用 C/C++书写代码时,应该处处留意如何处理来自用户的数据。如果一个函数的数据来源不可靠,又用到内存缓冲区,那么它就必须严格遵守下列规则:

    • 必须知道内存缓冲区的总长度。
    • 检验内存缓冲区。
    • 提高警惕。

     

    多态性,在c++中指具有不同功能的函数可以用同一个函数名,即可以用同一个函数名调用不同内容的函数。向不同的对象发送用一个消息,不同的对象在接收同样的消息,会产生不同的行为(方法)。
      从系统实现角度来看。多态性分为两类:静态多态性和动态多态性。
      静态多态性:在程序编译时系统就能决定调用哪个函数,因此静态函数又称编译时的多态性 ( 实质上是通过函数的重载实现 ) 。例如:函数的重载和运算符重载实现 .
      动态多态性:运行过程中才动态地确定操作指针所指的对象。主要通过虚函数和重写来实现。
    展开全文
  • 安全编程-缓冲区溢出

    千次阅读 2014-10-24 14:29:18
    缓冲区溢出指的是应用程序将数据写到一个较小缓冲区中所导致的程序漏洞。缓冲区溢出漏洞通常被攻击者用于重写内存中的数据。由于象C和C++语言,程序员可对内存进行操纵就会导致缓冲区溢出风险。 在C和C++程序中发现...

    缓冲区溢出指的是应用程序将数据写到一个较小缓冲区中所导致的程序漏洞。缓冲区溢出漏洞通常被攻击者用于重写内存中的数据。由于象CC++语言,程序员可对内存进行操纵就会导致缓冲区溢出风险。

    CC++程序中发现的很多早期缓冲区溢出漏洞,都是由字符串操作引起的。比如使用strcpy()strcat()这样的函数。针对这种情况,引入了这些函数的有边界限制的等价函数,如strncpy()strncat()。这些有界函数接收一个参数,限制写入到目标缓冲区中的数据总量。

    在使用不安全的编程语言时对字符串进行操作时要时刻小心。要当心用户的输入,限制长度和边界,采用一些安全的字符串类库将使应用程序更加安全。

    防止缓冲区溢出攻击的最佳方式是使用强制执行内存安全和类型安全的编程语言,例如Java语言和C#语言。安全语言应该具备确保程序内存分配范围的两种特性:内存安全和类型安全。内存安全是指程序不读入或者不写出超过所分配区域的数据。为了保证内存安全,编程语言必须强制类型安全,以记住内存分配边界。

    Java不要求程序员显示地分配内存和释放内存,都是由垃圾收集器自动执行的。垃圾收集器会不时检查个对象的各个引用,并回收无引用对象所占有的内存。判断一块内存空间是否符合回收标准有两个:

    1)给对象赋予了空值null,以后再也没有调用过。

    2)给对象赋予了新值,重新分配了内存空间。

    Java程序中也会出现内存泄漏的情况,即这些对象是可达的(会被引用),同时这些对象是无用的(程序以后不会再使用这些对象)。如满足这两个条件就说明对象不会被回收,一直占有着内存空间。

    下面给一个简单的内存泄漏的例子:

    Vector v = new Vector();

    for(int i=1;i<100;i++){

    Object o = new Object();

    v.add(o);

    o = null;

    }

    所有的Object对象都没有被释放,因为v引用了这些对象。

     

    整数溢出

    当一个整数值大于或者小于其范围时,就会产生整数溢出。因为所有内置整数类型(charshortintlong)都用一个固定的位数表示,所以其表示范围有限。当值超出最大或最小范围时,就会“回绕”。比如,一个非常大的整数变成一个负数。

    比如下面一段程序模拟一个电子商务站点。从页面读取购买商品的数量,假定每个商品价值100元。

    String numStr = request.getParamter("num");

    int numInt = Integer.parseInt(numStr);

    if(numInt > 0){

    int total = numInt * 100;

    }

    如果攻击者提供一个足够大的商品数量,例如42949671。乘以100后就超过了带符号的32位整数所表示的范围,总价将会是-196

    避免整数溢出问题的最好方法是,检验所有的整数输入是否都位于上下界范围内。上下界的选择应当使得任何后续计算结果都不会超出所使用变量的容量限制。

    java 定义了4个整数类型:字节型(byte),短整型(short),整型(int),长整型(long )。这些都是有符号的值,正数或是负数。Java 不支持仅仅是正的无符号的整数。

    名称类型长度范围
    字符型char byte8

    -128 ~ 127

    短整型short16

    32,768 ~ 32,767

    整型int32

    2,147,483,648 ~ 2,147,483,647

    长整型long64

    9,223,372,036,854,775,808 ~ 

                          9,223,372,036,854,775,807

     

    展开全文
  • 几个网络编程常用的数据结构

    千次阅读 2008-10-24 09:12:00
    netdevice - 底层访问 Linux 网络设备. 总览 (SYNOPSIS) #include < sys/ioctl.h > #include < net/if.h > 描述 (DESCRIPTION) 本手册 描述 用于 配置 网络设备 的 套接字(socket) 接口. Linux ...
    struct sockaddr_in {
    sa_family_t sin_family; /* address family: AF_INET */
    u_int16_t sin_port; /* port in network byte order */
    struct in_addr sin_addr; /* internet address */
    };

    struct in_addr {
    u_int32_t s_addr; /* address in network byte order */
    };

    struct sockaddr {
    ushort sa_family;
    char sa_data[14];
    };

    NAME

    netdevice - 底层访问 Linux 网络设备.

    总览 (SYNOPSIS)

    #include <sys/ioctl.h>
    #include <net/if.h>

    描述 (DESCRIPTION)

    本手册 描述 用于 配置 网络设备 的 套接字(socket) 接口.

    Linux 支持 一些 配置 网络设备 的 标准 ioctl. 他们 用于 任意的 套接字 描述符, 而 无须 了解 其 类型 或 系列. 他们 传递 一个 ifreq 结构:

    struct ifreq
    {
    char ifr_name[IFNAMSIZ]; /* Interface name */
    union {
    struct sockaddr ifr_addr;
    struct sockaddr ifr_dstaddr;
    struct sockaddr ifr_broadaddr;
    struct sockaddr ifr_netmask;
    struct sockaddr ifr_hwaddr;
    short ifr_flags;
    int ifr_ifindex;
    int ifr_metric;
    int ifr_mtu;
    struct ifmap ifr_map;
    char ifr_slave[IFNAMSIZ];
    char ifr_newname[IFNAMSIZ];
    char * ifr_data;
    };
    }

    struct ifconf
    {
    int ifc_len; /* size of buffer */
    union {
    char * ifc_buf; /* buffer address */
    struct ifreq *ifc_req; /* array of structures */
    };
    };

    一般说来, ioctl 通过 把 ifr_name 设置为 接口 的 名字 来 指定 将要 操作 的 设备. 结构的 其他成员 可以 分享 内存.

    IOCTLS

    如果 某个 ioctl 标记为 特权操作, 那么 操作时 需要 有效uid 为 0, 或者 拥有 CAP_NET_ADMIN 能力. 否则 将 返回 EPERM .

    SIOCGIFNAME
    给定 ifr_ifindex, 返回 ifr_name 中 的 接口名字. 这是 唯一 返回 ifr_name 内容 的 ioctl.
    SIOCGIFINDEX
    把 接口 的 索引 存入 ifr_ifindex.
    SIOCGIFFLAGS, SIOCSIFFLAGS
    读取 或 设置 设备的 活动标志字. ifr_flags 包含 下列值 的 屏蔽位:

    设备标志
    IFF_UP接口正在运行.
    IFF_BROADCAST有效的广播地址集.
    IFF_DEBUG内部调试标志.
    IFF_LOOPBACK这是自环接口.
    IFF_POINTOPOINT这是点到点的链路接口.
    IFF_RUNNING资源已分配.
    IFF_NOARP无arp协议, 没有设置第二层目的地址.
    IFF_PROMISC接口为杂凑(promiscuous)模式.
    IFF_NOTRAILERS避免使用trailer .
    IFF_ALLMULTI接收所有组播(multicast)报文.
    IFF_MASTER主负载平衡群(bundle).
    IFF_SLAVE从负载平衡群(bundle).
    IFF_MULTICAST支持组播(multicast).
    IFF_PORTSEL可以通过ifmap选择介质(media)类型.
    IFF_AUTOMEDIA自动选择介质.
    IFF_DYNAMIC接口关闭时丢弃地址.

    设置 活动标志字 是 特权操作, 但是 任何进程 都可以 读取 标志字.

    SIOCGIFMETRIC, SIOCSIFMETRIC
    使用 ifr_metric 读取 或 设置 设备的 metric 值. 该功能 目前 还没有 实现. 读取操作 使 ifr_metric 置 0, 而 设置操作 则 返回 EOPNOTSUPP.
    SIOCGIFMTU, SIOCSIFMTU
    使用 ifr_mtu 读取 或 设置 设备的 MTU(最大传输单元). 设置 MTU 是 特权操作. 过小的 MTU 可能 导致 内核 崩溃.
    SIOCGIFHWADDR, SIOCSIFHWADDR
    使用 ifr_hwaddr 读取 或 设置 设备的 硬件地址. 设置 硬件地址 是 特权操作.
    SIOCSIFHWBROADCAST
    使用 ifr_hwaddr 读取 或 设置 设备的 硬件广播地址. 这是个 特权操作.
    SIOCGIFMAP, SIOCSIFMAP
    使用 ifr_map 读取 或 设置 接口的 硬件参数. 设置 这个参数 是 特权操作.
    struct ifmap 
    {
    unsigned long mem_start;
    unsigned long mem_end;
    unsigned short base_addr;
    unsigned char irq;
    unsigned char dma;
    unsigned char port;
    };

    对 ifmap 结构 的 解释 取决于 设备驱动程序 和 体系结构.

    SIOCADDMULTI, SIOCDELMULTI
    使用 ifr_hwaddr 在 设备的 链路层 组播过滤器 (multicase filter) 中 添加 或 删除 地址. 这些是 特权操作. 参看 packet(7) .
    SIOCGIFTXQLEN, SIOCSIFTXQLEN
    使用 ifr_qlen 读取 或 设置 设备的 传输队列长度. 设置 传输队列长度 是 特权操作.
    SIOCSIFNAME
    ifr_ifindex 中 指定的 接口名字 改成 ifr_newname. 这是个 特权操作.
    SIOCGIFCONF
    返回 接口地址(传输层) 列表. 出于 兼容性, 目前 只代表 AF_INET 地址. 用户 传送 一个 ifconf 结构 作为 ioctl 的 参数. 其中 ifc_req 包含 一个 指针 指向 ifreq 结构数组, 他的 长度 以字节 为单位 存放在 ifc_len 中. 内核 用 所有 当前的 L3(第三层?) 接口地址 填充 ifreqs, 这些 接口 正在 运行: ifr_name 存放 接口名字 (eth0:1等), ifr_addr 存放 地址. 内核 在 ifc_len 中 返回 实际长度; 如果 他 等于 初始长度, 表示 溢出了, 用户 应该 换一个 大些的 缓冲区 重试 一下. 没有 发生 错误时 ioctl 返回 0, 否则 返回 -1, 溢出 不算 错误.

    大多数 协议 使用 自己的 ioctl 配置 协议 特定的 接口 操作. 具体 情况参看 协议的 帮助手册. 要配置 IP 地址 可以 参看 ip(7).

    另外, 某些 设备 有 专用的 ioctl, 这里 不做 叙述.

    注意 (NOTE)

    严格说来 SIOCGIFCONF 是 专门 针对 IP 的, 它 属于 ip(7).

    注意 (NOTE)

    可以 通过 /proc/net/dev 看到 没有 地址 或 没有 IFF_RUNNING 标志 的 接口名字.
    展开全文
  • 在数据包的首部,明确标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。 ① 应用程序处理 首先应用程序会进行编码处理,这些编码相当于 OSI 的表示层功能; 编码...

    目录

    一、OSI七层模型

    二、TCP/IP模型

    三、TCP/IP协议族

    四、TCP和UDP

    五、地址和端口号

    端口号的确定

    端口号与协议

    六、TCP/IP介绍

    6.1、TCP链接建立-三次握手

    TCP的三次握手的漏洞

    无效连接监视释放

    延缓TCB分配方法

    使用防火墙

    6.2、TCP链接的释放-四次挥手(分手)

    6.3、TCP/IP中的数据包

    6.4、TCP的通讯原理

    Socket套接字

    TCP缓冲区

    6.5、TCP 的可靠性

    6.6、TCP中的滑动窗口

    七、UDP协议

    八、HTTP协议介绍

    8.1、URI和URL的区别

    8.2、一个完整的URL

    8.3、HTTP请求的传输过程

    一次完整http请求的过程

    8.4、HTTP 协议报文结构

    请求报文结构

    响应报文结构

     


    一、OSI七层模型

    开放系统互连参考模型 (Open System Interconnect 简称OSI)是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型,为开放式互连信息系统提供了一种功能结构的框架。其目的是为异种计算机互连提供一个共同的基础和标准框架,并为保持相关标准的一致性和兼容性提供共同的参考。这里所说的开放系统,实质上指的是遵循OSI参考模型和相关协议能够实现互连的具有各种应用目的的计算机系统。

    OSI采用了分层的结构化技术,共分七层,物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

    二、TCP/IP模型

    OSI模型比较复杂且学术化,所以我们实际使用的TCP/IP模型,共分4层,链路层、网络层、传输层、应用层。两个模型之间的对应关系如图所示:

    无论什么模型,每一个抽象层建立在低一层提供的服务上,并且为高一层提供服务。

    三、TCP/IP协议族

    Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。协议采用了4层的层级结构。然而在很多情况下,它是利用 IP 进行通信时所必须用到的协议群的统称。也就是说,它其实是个协议家族,由很多个协议组成,并且是在不同的层, 是互联网的基础通信架构。

    四、TCP和UDP

    在上述表格中,网际协议IP是TCP/IP中非常重要的协议。负责对数据加上IP地址(有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址))和其他的数据以确定传输的目标。

    而TCP和UDP都是传输层的协议,传输层主要为两台主机上的应用程序提供端到端的通信。

    但是TCP和UDP最不同的地方是,TCP提供了一种可靠的数据传输服务,TCP是面向连接的,也就是说,利用TCP通信的两台主机首先要经历一个建立连接的过程,等到连接建立后才开始传输数据,而且传输过程中采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制,发送完成后还会关闭连接。所以TCP要比UDP可靠的多。

    UDP(User Datagram Protocol的简称, 中文名是用户数据报协议)是把数据直接发出去,而不管对方是不是在接收,也不管对方是否能接收的了,也不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。

    注意:

    我们一些常见的网络应用基本上都是基于TCP和UDP的,这两个协议又会使用网络层的IP协议。但是我们完全可以绕过传输层的TCP和UDP,直接使用IP,比如Linux中LVS,甚至直接访问链路层,比如tcpdump程序就是直接和链路层进行通信的。

    上图中,其他一些协议的名称解释,了解即可:

    ICMP  控制报文协议

    IGMP  internet组管理协议

    ARP   地址解析协议

    RARP 反向地址转化协议

    五、地址和端口号

    我们常听说 MAC 地址和 IP 地址。MAC地址就是在媒体接入层上使用的地址,也叫物理地址、硬件地址或链路地址,由网络设备制造商生产时写在硬件内部。MAC地址与网络无关,也即无论将带有这个地址的硬件(如网卡、集线器、路由器等)接入到网络的何处,都有相同的MAC地址,它由厂商写在网卡的BIOS里,从理论上讲,除非盗来硬件(网卡),否则是没有办法冒名顶替的。

    IP 地址后者用来识别 TCP/IP 网络中互连的主机和路由器。IP地址基于逻辑,比较灵活,不受硬件限制,也容易记忆。

    在传输层也有这种类似于地址的概念,那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。

    一台计算机上同时可以运行多个程序。传输层协议正是利用这些端口号识别本机中正在进行通信的应用程序,并准确地将数据传输。

    端口号的确定

    •    标准既定的端口号:这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。但并不是说可以随意使用任何一个端口号。例如 HTTP、FTP、TELNET 等广为使用的应用协议中所使用的端口号就是固定的。这些端口号被称为知名端口号,分布在 0~1023 之间;除知名端口号之外,还有一些端口号被正式注册,它们分布在 1024~49151 之间,不过这些端口号可用于任何通信用途。

    •    时序分配法:服务器有必要确定监听端口号,但是接受服务的客户端没必要确定端口号。在这种方法下,客户端应用程序完全可以不用自己设置端口号,而全权交给操作系统进行分配。动态分配的端口号范围在 49152~65535 之间。

    端口号与协议

    •    端口号由其使用的传输层协议决定。因此,不同的传输层协议可以使用相同的端口号。

    •    此外,那些知名端口号与传输层协议并无关系。只要端口一致都将分配同一种应用程序进行处理。

    六、TCP/IP介绍

    TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯。

    TCP提供的是一种可靠的数据流服务,采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。

    如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向‘上’传送到TCP层。TCP将包排序并进行错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。

    TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,设备驱动程序和物理介质,最后到接收方。

    面向连接的服务(例如TelnetFTPrloginX WindowsSMTP)需要高度的可靠性,所以它们使用了TCP。DNS在某些情况下使用TCP(发送和接收域名数据库),但使用UDP传送有关单个主机的信息。

    6.1、TCP链接建立-三次握手

    TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。

    所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

    第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。

    第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。

    第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

    通过linux下,tcpdump可以抓包,使用wireshark可以清楚地看到TCP建立连接的过程。

    TCP的三次握手的漏洞

    但是在TCP三次握手中是有一个缺陷的,就是如果我们利用三次握手的缺陷进行攻击。这个攻击就是SYN洪泛攻击。三次握手中有一个第二次握手,服务端向客户端应道请求,应答请求是需要客户端IP的,服务端是需要知道客户端IP的,攻击者就伪造这个IP,往服务器端狂发送第一次握手的内容,当然第一次握手中的客户端IP地址是伪造的,从而服务端忙于进行第二次握手但是第二次握手当然没有结果,所以导致服务器端被拖累,死机。

    当然我们的生活中也有可能有这种例子,一个家境一般的IT男去表白他的女神被拒绝了,理由是他家里没矿,IT男为了报复,采用了洪泛攻击,他请了很多人伪装成有钱人去表白那位追求矿的女神,让女生每次想交往时发现表白的人不见了同时还联系不上了。

    面对这种攻击,有以下的解决方案,最好的方案是防火墙。

    无效连接监视释放

    这种方法不停监视所有的连接,包括三次握手的,还有握手一次的,反正是所有的,当达到一定(与)阈值时拆除这些连接,从而释放系统资源。这种方法对于所有的连接一视同仁,不管是正常的还是攻击的,所以这种方式不推荐。

    延缓TCB分配方法

    一般的做完第一次握手之后,服务器就需要为该请求分配一个TCB(连接控制资源),通常这个资源需要200多个字节。延迟TCB的分配,当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。

    使用防火墙

    防火墙在确认了连接的有效性后,才向内部的服务器(Listener)发起SYN请求,

    6.2、TCP链接的释放-四次挥手(分手)

    四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

    由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

    1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
    2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
    3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
    4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
    5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

    服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

    抓包4次分手

    6.3、TCP/IP中的数据包

    每个分层中,都会对所发送的数据附加一个首部,在这个首部中包含了该层必要的信息,如发送的目标地址以及协议相关信息。通常,为协议提供的信息为包首部,所要发送的内容为数据。在下一层的角度看,从上一层收到的包全部都被认为是本层的数据。

    网络中传输的数据包由两部分组成:一部分是协议所要用到的首部,另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义。在数据包的首部,明确标明了协议应该如何读取数据。反过来说,看到首部,也就能够了解该协议必要的信息以及所要处理的数据。

    ① 应用程序处理
    首先应用程序会进行编码处理,这些编码相当于 OSI 的表示层功能;
    编码转化后,邮件不一定马上被发送出去,这种何时建立通信连接何时发送数据的管理功能,相当于 OSI 的会话层功能。

    ② TCP 模块的处理
    TCP 根据应用的指示,负责建立连接、发送数据以及断开连接。TCP 提供将应用层发来的数据顺利发送至对端的可靠传输。为了实现这一功能,需要在应用层数据的前端附加一个 TCP 首部。

    ③ IP 模块的处理
    IP 将 TCP 传过来的 TCP 首部和 TCP 数据合起来当做自己的数据,并在 TCP 首部的前端加上自己的 IP 首部。IP 包生成后,参考路由控制表决定接受此 IP 包的路由或主机。

     ④ 网络接口(以太网驱动)的处理
    从 IP 传过来的 IP 包对于以太网来说就是数据。给这些数据附加上以太网首部并进行发送处理,生成的以太网数据包将通过物理层传输给接收端。

    ⑤ 网络接口(以太网驱动)的处理
    主机收到以太网包后,首先从以太网包首部找到 MAC 地址判断是否为发送给自己的包,若不是则丢弃数据。
    如果是发送给自己的包,则从以太网包首部中的类型确定数据类型,再传给相应的模块,如 IP、ARP 等。这里的例子则是 IP 。

    ⑥ IP 模块的处理
    IP 模块接收到 数据后也做类似的处理。从包首部中判断此 IP 地址是否与自己的 IP 地址匹配,如果匹配则根据首部的协议类型将数据发送给对应的模块,如 TCP、UDP。这里的例子则是 TCP。
    另外吗,对于有路由器的情况,接收端地址往往不是自己的地址,此时,需要借助路由控制表,在调查应该送往的主机或路由器之后再进行转发数据。

    ⑦ TCP 模块的处理
    在 TCP 模块中,首先会计算一下校验和,判断数据是否被破坏。然后检查是否在按照序号接收数据。最后检查端口号,确定具体的应用程序。数据被完整地接收以后,会传给由端口号识别的应用程序。

    ⑧ 应用程序的处理
    接收端应用程序会直接接收发送端发送的数据。通过解析数据,展示相应的内容。

    6.4、TCP的通讯原理

    Socket套接字

    Socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)。

    区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

    套接字对是一个定义该连接的两个端点的四元组:本地IP地址、本地TCP端口号、外地IP地址、外地TCP端口号。套接字对唯一标识一个网络上的每个TCP连接。

    TCP缓冲区

    每个TCP的Socket的内核中都有一个发送缓冲区和一个接收缓冲区。现在我们假设用write()方法发送数据,使用 read()方法接收数据。

    write()并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。

    TCP协议独立于 write()函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

    read()也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。

    总得来说,I/O缓冲区在每个TCP套接字中单独存在;I/O缓冲区在创建套接字时自动生成;

    6.5、TCP 的可靠性

    在 TCP 中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答(ACK)。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,则数据丢失的可能性很大。

    在一定时间内没有等待到确认应答,发送端就可以认为数据已经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够到达对端,实现可靠传输。

    未收到确认应答并不意味着数据一定丢失。也有可能是数据对方已经收到,只是返回的确认应答在途中丢失。这种情况也会导致发送端误以为数据没有到达目的地而重发数据。

    此外,也有可能因为一些其他原因导致确认应答延迟到达,在源主机重发数据以后才到达的情况也屡见不鲜。此时,源主机只要按照机制重发数据即可。

    对于目标主机来说,反复收到相同的数据是不可取的。为了对上层应用提供可靠的传输,目标主机必须放弃重复的数据包。为此我们引入了序列号。

    序列号是按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据 TCP 首部中的序列号和数据的长度,将自己下一步应该接收的序列号作为确认应答返送回去。通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输。

    6.6、TCP中的滑动窗口

    发送方和接收方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接收方确认,目的是控制发送速度,以免接收方的缓存不够大导致溢出,同时控制流量也可以避免网络拥塞。

    在TCP 的可靠性的图中,我们可以看到,发送方每发送一个数据接收方就要给发送方一个ACK对这个数据进行确认。只有接收了这个确认数据以后发送方才能传输下个数据。

    存在的问题:如果窗口过小,当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。

    如果窗口过大,我们假设发送方一次发送100个数据,但接收方只能处理50个数据,这样每次都只对这50个数据进行确认。发送方下一次还是发送100个数据,但接受方还是只能处理50个数据。这样就避免了不必要的数据来拥塞我们的链路。

    因此,我们引入了滑动窗口。滑动窗口通俗来讲就是一种流量控制技术。

    它本质上是描述接收方的TCP数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据,如果发送方收到接收方的窗口大小为0的TCP数据报,那么发送方将停止发送数据,等到接收方发送窗口大小不为0的数据报的到来。

    首先是第一次发送数据这个时候的窗口大小是根据链路带宽的大小来决定的。我们假设这个时候窗口的大小是3。这个时候接受方收到数据以后会对数据进行确认告诉发送方我下次希望手到的是数据是多少。这里我们看到接收方发送的ACK=3(这是发送方发送序列2的回答确认,下一次接收方期望接收到的是3序列信号)。这个时候发送方收到这个数据以后就知道我第一次发送的3个数据对方只收到了2个。就知道第3个数据对方没有收到。下次在发送的时候就从第3个数据开始发。

    此时窗口大小变成了2 。

    于是发送方发送2个数据。看到接收方发送的ACK是5就表示他下一次希望收到的数据是5,发送方就知道我刚才发送的2个数据对方收了这个时候开始发送第5个数据。

    这就是滑动窗口的工作机制,当链路变好了或者变差了这个窗口还会发生变话,并不是第一次协商好了以后就永远不变了。                

    所以滑动窗口协议,是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。

    只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。   

    收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。   

    七、UDP协议

    UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。

    UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。

    UDP与TCP位于同一层,但它不管数据包的顺序、错误或重发。因此,UDP不被应用于那些面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。相对于FTP或Telnet,这些服务需要交换的信息量较小。使用UDP的服务包括NTP(网络时间协议)和DNS(DNS也使用TCP),包总量较少的通信(DNS、SNMP等);2.视频、音频等多媒体通信(即时通信);3.限定于 LAN 等特定网络中的应用通信;4.广播通信(广播、多播)。

    常用的QQ,就是一个以UDP为主,TCP为辅的通讯协议。

    TCP 和 UDP 的优缺点无法简单地、绝对地去做比较:TCP 用于在传输层有必要实现可靠传输的情况;而在一方面,UDP 主要用于那些对高速传输和实时性有较高要求的通信或广播通信。TCP 和 UDP 应该根据应用的目的按需使用。

    八、HTTP协议介绍

    HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

    我们使用http来访问Web上某个资源,比如html/文本、word、avi电影、其他资源。

    Content-Type指示响应的内容,这里是text/html表示HTML网页。请注意,浏览器就是依靠Content-Type来判断响应的内容是网页还是图片,是视频还是音乐。浏览器并不靠URL来判断响应的内容,所以,即使URL是http://example.com/abc.jpg,它也不一定就是图片。

    HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。

    URL,全称是UniformResourceLocator, 中文叫统一资源定位符,是互联网上用来标识某一处资源的地址。

    8.1、URI和URL的区别

    URI是个纯粹的句法结构,用于指定标识Web资源的字符串的各个不同部分。URL是URI的一个特例,它包含了定位Web资源的足够信息。其他URI,比如

    mailto:cay@horstman.com

    则不属于定位符,因为根据该标识符无法定位任何资源。

    URI 是统一资源标识符,而 URL 是统一资源定位符。因此,笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。上面的 mailto就是一个URN 的示例。

    URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。

    8.2、一个完整的URL

    包括以下几部分:

    http://www.enjoyedu.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

    1.协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符

    2.域名部分:该URL的域名部分为“www.enjoyedu.com”。一个URL中,也可以使用IP地址作为域名使用

    3.端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口

    4.虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”

    5.文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名

    6.锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分

    7.参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。

    8.3、HTTP请求的传输过程

    首先作为发送端的客户端在应用层(HTTP 协议)发出一个想看某个 Web 页面的 HTTP 请求。

    接着,为了传输方便,在传输层(TCP 协议)把从应用层处收到的数据(HTTP 请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。

    在网络层(IP 协议),增加作为通信目的地的 MAC 地址后转发给链路层。这样一来,发往网络的通信请求就准备齐全了。

    接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP请求。

    一次完整http请求的过程

    首先进行DNS域名解析(本地浏览器缓存、操作系统缓存或者DNS服务器)

    建立 TCP 连接

    在HTTP工作开始之前,客户端首先要通过网络与服务器建立连接,该连接是通过 TCP 来完成的,该协议与 IP 协议共同构建 Internet,即著名的 TCP/IP 协议族,因此 Internet 又被称作是 TCP/IP 网络。HTTP 是比 TCP 更高层次的应用层协议,根据规则,只有低层协议建立之后,才能进行高层协议的连接,因此,首先要建立 TCP 连接,一般 TCP 连接的端口号是80;

    •  客户端向服务器发送请求命令

    一旦建立了TCP连接,客户端就会向服务器发送请求命令;

    例如:GET/sample/hello.jsp HTTP/1.1

    •  客户端发送请求头信息

    客户端发送其请求命令之后,还要以头信息的形式向服务器发送一些别的信息,之后客户端发送了一空白行来通知服务器,它已经结束了该头信息的发送;

    •  服务器应答

    客户端向服务器发出请求后,服务器会客户端返回响应;

    例如: HTTP/1.1 200 OK

    响应的第一部分是协议的版本号和响应状态码

    •  服务器返回响应头信息

    正如客户端会随同请求发送关于自身的信息一样,服务器也会随同响应向用户发送关于它自己的数据及被请求的文档;

    •  服务器向客户端发送数据

    服务器向客户端发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以 Content-Type 响应头信息所描述的格式发送用户所请求的实际数据;

    •  服务器关闭 TCP 连接

    一般情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接,然后如果客户端或者服务器在其头信息加入了这行代码 Connection:keep-alive ,TCP 连接在发送后将仍然保持打开状态,于是,客户端可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。

    以下为整个HTTP请求的抓包

    8.4、HTTP 协议报文结构

    用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文;响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。

    HTTP 报文大致可分为报文首部和报文主体两部分。两者由最初出现的空行(CR+LF)来划分。通常,并不一定有报文主体。

    请求报文结构

    请求报文的首部内容由以下数据组成:

    请求行 —— 包含用于请求的方法、请求 URI 和 HTTP 版本。

    首部字段 —— 包含表示请求的各种条件和属性的各类首部。(通用首部、请求首部、实体首部以及RFC里未定义的首部如 Cookie 等)

    响应报文结构

    状态行 —— 包含表明响应结果的状态码、原因短语和 HTTP 版本。

    首部字段 —— 包含表示请求的各种条件和属性的各类首部。(通用首部、响应首部、实体首部以及RFC里未定义的首部如 Cookie 等)

     

    展开全文
  • Windows网络编程

    万次阅读 2007-12-13 16:58:00
    第一章 序言 我写这个专题的目的,一方面是为了通过对网络编程再一次系统的总结,提高自己的网络编程水平,特别是Windows下的网络编程水平。同时,我也希望,能为众多初学网络编程的人提供一点帮助,因为我开始学习...
  • 网络编程知识

    千次阅读 2010-04-09 18:12:00
    网络编程知识索引:处理SIGCHLD信号捕获信号时,注意处理被中断的系统调用accept返回前连接夭折的处理具有多个输入的处理SIGPIPE的产生和处理处理服务器主机崩溃处理服务器主机崩溃重启处理服务器主机关机网络函数的...
  • 浅谈网络编程中的常见问题

    万次阅读 2019-08-27 17:43:47
    OSI七层模型 OSI七层协议模型主要是: 应用层(Application) ...数据链路层(Data Link) 物理层(Physical) 2.TCP/IP五层模型 TCP/IP五层模型: 应用层(Application) 传输层(Transport) 网络层(Network...
  • 后端网络编程知识点总结

    千次阅读 2016-10-02 18:26:48
    这一篇是网络编程的面试知识点的总结。不打算从计算机网络的基础讲起,只是摘要性的总结一下知识点,更多的内容请从经典的书籍中获取。1、tcp与udp的区别(必问) 可靠性 首先,TCP是一个面向连接的协议,需要三次...
  • 安全编程: 防止缓冲区溢出

    千次阅读 2010-09-03 16:42:00
    本文讨论 Linux/UNIX 系统中最常见的缺陷:缓冲区溢出。本文首先解释什么是缓冲区溢出,以及它们为何如此常见和如此危险。然后讨论广泛用于解决缓冲区溢出的新 Linux 和 UNIX 方法 ―― 以及为什么这些方法还...
  • 网络编程面试题

    千次阅读 2015-04-11 19:45:44
    1`. 问MainFrm,CDocument和CView类之间的关系, MainFrm为框架类,包含应用程序外框所包含部分。...其中文档类CDocument用于数据的存储和加载,视类CView用于数据的显示与修改。 2. Dialog和 Mo
  • asp网络编程

    万次阅读 2008-05-31 21:53:00
    用ASP编程实现网络内容快速查找 有一天我突发奇想,要是我每到一个网站,那里都能立刻调出我需要看的信息,那岂非美妙得很。接下来我想更深入地考虑这个问题,坐到椅子上拿一支铅笔,却不知道自己写什么。如此一来,...
  • 网络编程知识点梳理

    千次阅读 2017-08-06 11:42:38
    3 ISO七层网络模型五层网络模型TCPIP四层网络模型 4 TCP和UDP的区别 5 同步和异步阻塞和非阻塞长线程和短线程的区别 6 现在要访问wwwbaiducom整个过程是怎样的 6 IPTCP首部 7 TCP三次握手及四次挥手 8 DNS是什么本机...
  • UNIX网络编程---套接字编程简介 一、概述 从这里开始正式开始网络编程之旅,所有的函数都是基本的库函数。这些都是网络编程的基础。Come on!!!! 二、套接字地址结构 大多数套接字函数都需要一个指向套接字地址结构...
  • Android网络数据传输之网络协议

    千次阅读 2015-10-30 11:46:50
    Android网络数据传输之网络协议说起网络数据之间的交互,我们就必须明白下网络的分层,知道网络从后台到客户端看到的有哪些步骤。网络的七层分层在实际手机端开发中,我们主要是通过接口向后台请求数据,然后数据...
  • C++编程中如何防止内存溢出问题?

    千次阅读 2015-05-04 21:08:11
    1. 良好的编程习惯是预防内存漏洞的根本 2. 正确申请和释放内存空间。 3. 记得在每个可能的出口检查指针 一、为什么会出现内存溢出问题? 导致内存溢出问题的原因有很多,比如: (1) 使用非类型安全(non-type...
  • linux C网络编程基本流程

    千次阅读 2011-10-22 12:14:00
    Linux C编程---网络编程  网络编程,一定离不开套接口;那什么是套接口呢?在Linux下,所有的I/O操作都是通过读写文件描述符而产生的,文件描述符是一个和打开的文件相关联的整数,这个文件并不只包括真正存储在...
  • Linux网络编程函数

    千次阅读 2012-10-09 09:34:19
    1.字节序函数 #include uint16_t htons(uint16_t host16bitvalue); uint32_t htonl(uint32_t ...返回:网络字节序值 uint16_t ntohs(uint16_t net16bitvalue); uint32_t ntohl(uint32_t net32bitvalue); 返回:主
  • 套接字编程简介
  • java基础知识——网络编程、IO流

    千次阅读 2016-01-06 20:36:44
    IO流字节流:处理字节数据的流对象,计算机中最小数据单元就是字节。InputStream OutputStream字符流:字符编码问题,将字节流和编码表封装成对象就是字符流。Reader Write读、写都会发生 IO 异常。io 异常的处理...
  • 一、介绍基于TCP协议通过socket实现网络编程常用API 1、读者如果不是很熟悉,可以先看我之前写的几篇博客,有socket,地址结构的理解,更加方便读者理解 地址分别是: 1)、...
  • UNIX网络编程笔记(1)—传输层协议

    千次阅读 2016-05-17 11:25:46
    UNIX网络编程,传输层协议简介
  • TCP网络编程MSS细节

    千次阅读 2012-05-06 18:39:29
      8.I/O通信 ...从I/O的角度来看,套接字也是文件,它提供了同文件读写(fread()/fwrite())对应的收发数据操作接口:send()/recv()。 8.1 发送数据 8.1.1 send // The send function sends data
  • DAQmx数据采集缓冲区溢出分析

    千次阅读 2018-11-14 23:09:00
    在使用DAQmx采集数据时,有时会发生缓冲区溢出现象,通常的表现为采集数据不正确,并出现200279错误。下面分析缓冲区原理及溢出原因: 外部的信号进入数据采集卡后,经过各种处理转换,先进入数据采集卡自身的缓冲区...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,425
精华内容 29,370
关键字:

网络编程数据读取溢出