如何判断TCP包是否发送成功

news/2024/5/17 15:30:35 标签: 个人笔记, tcp

原文地址:http://blog.csdn.net/ordeder/article/details/17240221

1. TCP发送接口:send()

  TCP发送数据的接口有send,write,sendmsg。在系统内核中这些函数有一个统一的入口,即sock_sendmsg()。由于TCP是可靠传输,所以对TCP的发送接口很容易产生误解,比如sn = send(...); 错误的认为sn的值是表示有sn个字节的数据已经发送到了接收端。其实真相并非如此。

        我们知道,TCP的发送和接收在在内核(linux)中是有对应的缓冲的:

struct sock{
...
struct sk_buff_head    receive_queue;    //接收的数据报队列
struct sk_buff_head    write_queue;    //即将发送的数据报队列
...
}

 

  对于发送端而言,用户空间调用send(data)等发送接口将数据发送,内核会将data拷贝到内核空间的socket对应的缓冲中,即sock.write_queue。而send()函数的返回值仅仅是表示本次send()调用中成功拷贝的字节数(用户空间->内核空间对应的sock缓冲队列)具体发送和接收端的接收就由TCP协议完成,虽然TCP是可靠传输,但是这个前提是发送端和接收端的网络是连接的,否则你懂得。这样,对于调用send()发送的用户而言,如果想要确定接收方是否成功接受数据,就得需要靠其他的办法查询。

 

2. send()阻塞和非阻塞

  

前面已说过,sn=send(data)负责将数据拷贝到内核空间,而具体发送是有tcp后续完成(这里面就包括流量控制等)。对已阻塞和非阻塞仅仅是对于数据从用空空间拷贝到内核空间的发送缓冲这段期间而言的

        1. 如果发送缓冲剩余空间大于欲发送data的字节数,对于阻塞和非阻塞而言都能成功将数据拷贝至内核缓冲,返回的sn即等于欲发送的数据的字节数。

        2.如果发送缓冲剩余空间小于欲发送data的字节数,

                    a. 那么阻塞模式会进行阻塞,等待内核缓冲的空闲空间,然后继续将数据拷贝到内核缓冲中,直到全部拷贝为止。返回rn即为data的数据量。

                    b. 非阻塞模式,当内核发送缓冲被填满后,立即返回。rn等于data中已被拷贝到发送缓冲的数据量。

 

3. 如何判定接收成功接收数据?

 1.接收端回复应答信息。

      这个方法比较土,但也是比较实用的。

 2.计算发送端sock已发送数据量

     可参考:如何判断TCP数据包是否发送成功 作者提到可以使用 ioctl接口:ioctl(tcp_socket, SIOCOUTQ, &value);

 



http://www.niftyadmin.cn/n/948787.html

相关文章

为什么使用CreateThread时不建议调用RTC函数

原文地址:http://blog.csdn.net/allen_1986/article/details/6530329 改变了栈的大小,但是把CreateThread的第2参数改成0x100000或者更小的时候,程序还是会出现这样的问题,只有将栈的大小还原为默认值,且CreateThread的…

RAD Studio EX5帮助文档不能打开

今天装完RAD Studio EX5后,打开帮助文档,出现ms-help://XXXX无法找到的错误。 跟同学用的同样的安装包,采取的同样的安装破解步骤,结果他的帮助文档却可以正常打开。 于是去网上搜解决方法。 下面的方法奏效: 运行…

C/C++ 排序算法大全代码

原文地址:http://blog.csdn.net/johnnyhu90/article/details/12447777 C/C 排序算法大全代码 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838…

VS2013在文件中查找时无法显示查找结果

VS2013用“在文件中查找”时,只能显示有没有找到,但是不能显示查找到的具体内容。 原文地址:http://blog.csdn.net/cml2030/article/details/46805701 问题的现象:通过使用 Ctrl Shift F 也就是Find In Files功能,使用之后只能…

C++回调接口声明

用Java写回调函数时,用interface可以很方便的声明和实现回调接口。 c声明回调接口可以声明一个纯虚类。 什么是纯虚类? 答:纯虚类就是一个只有声明没有实现的类。 如 class aInterFace { virtual void fun() 0; } 注意:v…

移动鼠标时得不到WM_MOUSEMOVE消息

原因&#xff1a; 在写一个解方程的函数时&#xff0c;逻辑出了问题。错误如下&#xff1a; 解出来一个角的sin值为-1.19&#xff0c;然后对-1.19求反正弦。这尼玛必然是错的啊。但是调用<math.h>的asin求该值时&#xff0c;并没有抛出异常。于是&#xff0c;就导致了如…

由S_ISDIR学到的

今天帮旭哥哥看程序&#xff0c;需要编译libconfig这个库。该库的源码里用到了S_ISDIR&#xff0c;在编译时却报错说没有找到该声明。在网上一番搜索之后发现&#xff0c;这个宏是Linux里才有的&#xff0c;在Windows没有这个宏。&#xff08;Linux环境中它在sys/stat.h中定义&…

多范式编程语言

概要&#xff1a; 本文主要讲述了三种编程范式——面向对象编程、函数式编程、泛型编程的概念编程范式 编程范式是程序语言背后的思想。代表了程序设计者认为程序应该如何被构建和执行的看法。常见的编程范式有&#xff1a;过程式&#xff0c;面向对象&#xff0c;函数式&#…