LINUX socket SIOCOUTQ获取发送队列信息

原创 2018年04月16日 15:13:04

在某C/S结构程序测试时发现一个问题

当无线网络拥塞的时候,无线层丢包很严重,TCP socket可能需要若干秒(worst case n>5)才能发出去。

发送方调用write(fd)将报文发送的时候实际上只是写入了内核的write buffer。接收方什么时候能收到报文是个未知数。

在某些需要同步状态机的地方,发送方最好能够确认接收方收到报文后再进行下一步动作。

C: How to tell the status of a socket
by George Michael|Published 30 October 2011
If you are trying to check if a socket is empty but you cannot use select(), because what you need is to check the write buffers instead of the read ones just to be sure that you have successfully managed to send all data to your peers before terminating, or if you want to tell if a socket buffer is full.

You can use the ioctl to find out.

To check a write buffer if it empty (assuming you have already put data there and want to check if they were consumed):

ioctl(fd, SIOCOUTQ, &pending);
Where fd is the socket’s file descriptor and pending the variable were the remaining size of data will be returned.

To check a read buffer if it empty (assuming someone has already put data there and you want to check if they there is any without consuming them):

ioctl(fd, SIOCINQ, &pending);
*note the difference on the second parameter, where we change the flag from SIOCOUTQ to SIOCINQ
Among other includes be sure to add these:

#include <sys/ioctl.h>
#include <linux/sockios.h>

linux提供了ioctl(fd, SIOCOUTQ, &count)方法来查询一个tcp socket的write buffer是否清空。发送方一般可以用这个方法来判断对端是否收到报文。

调试程序的时候遇到了一个奇怪的问题。

CLIENT端实际上已经收到了SERVER发送的报文,开始进行下一步动作。 但是SERVER端的out queue始终显示没有发送完毕。

经过Debug后发现,实际上是client端收到报文后发送给server的TCP ACK在空口中丢失。尽管client端已经接收完毕数据,但是由于server端没有收到对应的ack,导致server端一直认为发送端没有收到数据。


所以发送方可以通过SIOCOUTQ来辅助判断tcp socket的状态。但是最好还是不要用SIOCOUTQ来绑定程序逻辑。不然容易造成死锁。



HR-XML(可扩展人力资源标准)简介

HR-XML(可扩展人力资源标准)简介Flyspace (flyspace@x263.net)      2003年12月12日  标准出处:http://www.hr-xml.org标准简介:什么是...
  • FlySpace
  • FlySpace
  • 2003-12-13 02:25:00
  • 4734

linux tcp socket的发送与接收缓冲区

  应用程序可通过调用send(write, sendmsg等)利用tcp socket向网络发送应用数据,而tcp/ip协议栈再通过网络设备接口把已经组织成struct sk_buff的应用数据(t...
  • jhfeng2002
  • jhfeng2002
  • 2011-04-07 13:42:00
  • 8730

Linux网络编程之socket:使用select函数实现并发处理

一、当我们使用单进程单连接且使用readline修改后的客户端程序,去连接使用readline修改后的服务器端程序,会出现一个有趣的现象,先来看输出: 先运行服务器端,再运行客户端。...
  • u012814360
  • u012814360
  • 2014-10-21 19:19:49
  • 3182

Linux进程间通信方式--本地socket

先上一个代码 服务端: //s_unix.c #include #include #include #include #define UNIX_DOMAIN "/tmp/UNIX.domai...
  • shanzhizi
  • shanzhizi
  • 2013-11-22 12:30:46
  • 44870

epoll+socket实现并发服务器 Linux C(版本一)

这个是第一个版本。以后本人会逐渐完善。 #include #include #include #include #include #include #include #include #includ...
  • u012997311
  • u012997311
  • 2017-06-23 21:28:58
  • 350

Linux C TCPSocket 传输文件简单实例-多线程实现

在Linux下使用C语言TCPSocket实现简单文件传输,包括客户端和服务器端,其中,服务器端使用多线程实现同时接收多个客户端发送的文件。发送文件内容之前,首先需要将文件名和长度信息发送到服务器,为...
  • wanna_wsl
  • wanna_wsl
  • 2016-12-21 22:04:14
  • 3283

linux socket 编程

socket    目 录 socket socket() bind() connect() listen() accept() send() 和recv() sendto() 和recvfrom()...
  • kakaka2011
  • kakaka2011
  • 2011-07-13 11:16:39
  • 359

Linux下socket编程

一 TCP/IP与套接字 - 套接字是通信端点的抽象 - 套接字同样适用于本地的通信,代替管道 - wirte和read同样适用于套接字二 TCP通讯 1)tcp使用的过程, client端,主动连接...
  • sinat_29173167
  • sinat_29173167
  • 2016-12-10 17:33:12
  • 567

Linux进程间通信 - 消息队列

Linux进程间通信 - 消息队列1 简介Linux和类Linux系统下进程间通信(Inter-Process Communication, IPC)有很多种方式,包括套接字(socket),共享内存...
  • junyucsdn
  • junyucsdn
  • 2015-12-27 17:07:34
  • 677

socket 的通信过程

下图是基于TCP协议的客户端/服务器程序的一般流程: 服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客...
  • bravegogo
  • bravegogo
  • 2016-03-01 22:51:54
  • 165
收藏助手
不良信息举报
您举报文章:LINUX socket SIOCOUTQ获取发送队列信息
举报原因:
原因补充:

(最多只允许输入30个字)