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

来源:互联网 发布:淘宝上的喵喵通讯 编辑:程序博客网 时间:2024/06/05 14:09

/* Linux-specific socket ioctls */#define SIOCINQ        FIONREAD#define SIOCOUTQ    TIOCOUTQ#define SIOCATMARK    _IOR('s', 7, int)一个应用程序可以使用SIOCATMARK ioctlsocket()命令来确定在记号之前是否还有未读入的数据。应用程序可以使用这一记号与其对方进行重新同步。


SIOCINO 能得到未读的数据 只对TCP SOCKET
              int value;              error = ioctl(unix_socket, ioctl_type, &value);       ioctl_type can be:       SIOCINQ              For SOCK_STREAM socket the function returns the amount of              queued unread data in the receive buffer.  The socket must not              be in LISTEN state, otherwise an error (EINVAL) is returned.              SIOCINQ is defined in <linux/sockios.h>.  Alternatively, you              can use the synonymous FIONREAD, defined in <sys/ioctl.h>.              For SOCK_DGRAM socket, the returned value is the same as for              Internet domain datagram socket; see udp(7).


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

(2013-11-02 22:44:01)
转载
标签:

tcp数据发送

成功

tcp

分类:tcpip
问题描述:socket编程,发送少量数据时,send/write等发送函数会立即返回成功,发送的数据会存在TCP发送缓冲区中,依靠TCP协议栈自身的重传机制来保证该数据 被接收端收到;我们的问题是 发送端应用程序 如何判断 少量数据 已经成功发送到接收端?

解决思路:发送数据存在缓冲区中,我们判断发送缓冲区大小变化,即可获知发送是否成功;具体方法如下:发送数据后,获得已使用缓冲区大小buf,如果buf==0,表示成功,否则,表示未发送;
那么,如何来获得当前已占用发送缓冲区大小?
1. 第一步我们自然想到是否存在这样的sockopt接口
getsockopt(clientSocket, SOL_SOCKET, SO_SNDBUF, (void*)&sendbuflen, &len);
getsockopt中,有参数SO_SNDBUF,貌似是用来获得发送缓冲大小的;
但经过试验,我们发现 无论数据是否发送成功,该值一直不变;
查看内核代码,发现 该参数的含义是 总共的发送缓冲区,包括 已占用 和 空闲的;

2. 第二步,我们发现
/proc/net/tcp 中tx_queue大小,即已占用发送缓冲区大小
/proc/net/tcp 中tx_queue 的计算:“tp->write_seq tp->snd_una”,根据该计算方法,在内核源码中查找,发现内核导出了2个获得已使用发送缓冲的编程接口;
  1. ioctl接口:ioctl(tcp_socket, SIOCOUTQ, &value);
  2. netlink接口:socket(AF_NETLINK,SOCK_RAW, NETLINK_TCPDIAG);获得structtcpdiagmsg结构体数据,其中,tcpdiag_wqueue即已占用发送缓冲区大小;

ps:ioctl接口已经实验验证可用,netlink尚未验证,可参考http://linux.chinaunix.net/techdoc/develop/2006/10/15/942169.shtml;

0 0