SO_LINGER
此选项指定函数close对面向连接的协议如何操作(如TCP)。缺省close操作是立即返回,如果有数据残留在套接口缓冲区中则系统将试着将这些数据发送给对方。
SO_LINGER选项用来改变此缺省设置。使用如下结构:
struct linger {
int l_onoff; /* 0 = off, nozero = on */
int l_linger; /* linger time */
};
有下列三种情况:
- l_onoff为0,则该选项关闭,l_linger的值被忽略,等于缺省情况,close立即返回;
l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
- l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。
如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列(描述字访问计数为0)或(b)延迟时间到。
此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。
close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完 成。
- l_linger的单位依赖于实现,4.4BSD假设其单位是时钟滴答(百分之一秒),但Posix.1g规定单位为秒。
--------------------------------华丽的分割线---------------------------------------------------
TCP_NODELAY和TCP_CORK
基本上控制了包的“Nagle化”,Nagle化在这里的含义是采用Nagle算法把较小的包组装为更大的帧。
John
Nagle是Nagle算法的发明人,后者就是用他的名字来命名的,他在1984年首次用这种方法来尝试解决福特汽车公司的网络拥塞问题(欲了解详情请参
看IETF RFC 896)。
他解决的问题就是所谓的silly window syndrome
,中文称“愚蠢窗口症候群”,具体含义是:
因为普遍终端应用程序每产生一次击键操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据载荷以及40
个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞,。
Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为缺省配置了,但在我们看来,有些场合下把这一选项关掉也是合乎需要的。
现在让我们假设某个应用程序发出了一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。
如果我们马上发
送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。
例如,当我们正在发送一个较短的请求并且等候较大的响应时,相关过载与传输的数据总量相
比就会比较低,而且,如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的TCP_NODELAY选项来完成,这样就禁用了Nagle
算法。
另外一种情况则需要我们等到数据量达到最大时才通过网络一次发送全部数据,这种数据传输方式有益于大量数据的通信性能,典型的应用就是文件服务器。应用
Nagle算法在这种情况下就会产生问题。
但是,如果你正在发送大量数据,你可以设置TCP_CORK选项禁用Nagle化,其方式正好同
TCP_NODELAY相反(TCP_CORK 和 TCP_NODELAY 是互相排斥的)。
下面就让我们仔细分析下其工作原理。
假设应用程序使用sendfile()函数来转移大量数据。应用协议通常要求发送某些信息来预先解释数据,这些信息其实就是报头内容。典型情况下报头很
小,而且套接字上设置了TCP_NODELAY。
有报头的包将被立即传输,在某些情况下(取决于内部的包计数器),因为这个包成功地被对方收到后需要请求
对方确认。
这样,大量数据的传输就会被推迟而且产生了不必要的网络流量交换。
但是,如果我们在套接字上设置了TCP_CORK(可以比喻为在管道上插入“塞子”)选项,具有报头的包就会填补大量的数据,所有的数据都根据大小自动地
通过包传输出去。当数据传输完成时,最好取消TCP_CORK
选项设置给连接“拔去塞子”以便任一部分的帧都能发送出去。这同“塞住”网络连接同等重要。
总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的头和正文),那么我们建议你设置TCP_CORK选项,这样在这些数据之间不存在延迟。
能极大地有益于WWW、FTP以及文件服务器的性能,同时也简化了你的工作。
--------------------------------华丽的分割线---------------------------------------------------
SO_REUSEADDR
套接字选项:使两个server socket可以监听同一个端口
默认情况下,套接字不同一个正在使用的本地地址绑定到一起。但在少数情况下,仍有必要以这种方式,来实现对一个地址的重复利用。
通过第7章的学习,大家已
经知道,每个连接都是通过它的本地及远程地址的组合,“独一无二”地标识出来的。针对我们想要连接的地址,只要能用极其细微的差异(比如TCP/IP中采用不同的端口号),来维持这种“独一无二”或者“唯一”的特点,绑定便是允许的。
唯一例外的是监听套接字。两个独立的套接字不可与同一个本地接口
(在TCP/IP的情况下,则是端口)绑定到一起,以等待进入的连接通知。
假定两个套接字都在同一个端口上进行监听,那么到底由谁来接收一个进入连接通知呢?对于这个问题,目前尚无一种正式规范提出了解决方案。
在TCP的环境下,假如服务器关闭,或异常退出,造成本地地址和端口均进入TIME_WAIT状态,那么SO_REUSEADDR 这个套接字选项便显得非常有用。
在TIME_WAIT状态下,其他任何套接字都不能与那个端口绑定到一起。但假若设置了该选项,服务器便可在重新启动之后,在相同的本地接口及端口上进行监听。
将服务端socket套接字设置上SO_REUSEADDR属性,代码如下:
//设置socket套接字的属性:允许多个设备在同一个本地网中监听同一下端口
int one = 1;
if (sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
printf("setsockopt SO_REUSEADDR error\n");
close(sock);
return;
}
这么设置套接字的作用是:允许两个server端的套接字在同一个本地网段中监听同一个端口.
--------------------------------华丽的分割线---------------------------------------------------
SO_KEEPALIVE
保持连接检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。
设置该选项后,如果2小时内在此套接口的任一方向都没有数据交换,TCP就自
动给对方 发一个保持存活探测分节(keepalive
probe)。这是一个对方必须响应的TCP分节.它会导致以下三种情况:
- 对方接收一切正常:以期望的ACK响应。2小时后,TCP将发出另一个探测分
节。
- 对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接
口本身则被关闭。
- 对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到一个响应。在发出第一个探测分节11分钟
15秒后若仍无响应就放弃。
套接口的待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host
unreachable(主机不可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为 EHOSTUNREACH。
在该书的第158页有更详细的描述。
根据上面的介绍我们可以知道对端以一种非优雅的方式断开连接的时候,我们可以设置SO_KEEPALIVE属性使得我们在2小时以后发现对方的TCP连接
是否依然存在。
keepAlive = 1;
Setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));
如果我们不能接受如此之长的等待时间,从TCP-Keepalive-HOWTO上可以知道一共有两种方式可以设置,一种是修改内核关于网络方面的配置参
数,另外一种就是SOL_TCP字段的TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT三个选项。
分享到:
相关推荐
本资源提供的`socket函数说明.docx`文档详细介绍了在Windows环境下,使用Microsoft开发工具进行Socket编程时的各种函数用法,这对于中文使用者来说是一个非常宝贵的参考资料。 首先,我们从基础开始,`socket()`...
一个 Socket 包括 IP 地址和端口号,这两个参数共同标识了一个特定的网络连接。 2. **Socket类型**:主要分为两种类型: - **流式 Socket (TCP)**:基于 TCP 协议,提供面向连接的服务,确保数据的可靠传输。 - **...
### Socket编程核心函数详解 #### 1. accept(接受socket连接) `accept()`函数是用于接收客户端连接请求的关键函数,通常在服务器端编程中使用。它等待并接收来自客户端的连接请求,一旦接收到请求,它会创建一个新...
【基于SuperSocket的消息推送详细说明文档1】 本文档将详细阐述一个基于SuperSocket实现的消息推送项目的构建和工作原理。该项目旨在模拟手机APP向用户推送消息的功能,通过B/S(浏览器/服务器)和C/S(客户端/...
- **Socket API详解**:详细解释Socket创建、连接、发送、接收、关闭等函数的使用方法和参数含义。 - **异常处理**:阐述如何处理网络通讯中可能出现的各种异常情况,如超时、连接中断等。 - **多线程编程**:讲解...
- **参数说明**: - 第一个参数指定地址族,此处为 `AF_INET`,即 IPv4。 - 第二个参数指定 Socket 类型,此处为 `SOCK_STREAM`,表示流式套接字(TCP)。 - 第三个参数指定协议,通过 `getprotobyname()` 函数...
这通常涉及到创建Socket对象,设置连接参数(如IP地址和端口号),建立连接,发送和接收数据,以及处理连接的断开等基本操作。 在标签"pb socket"中,"pb"显然是指Progress Bar,而"socket"则指的是Socket编程。这...
MySQL 参数说明 MySQL 的参数配置在 my.cnf 文件中,参数和 SHOW VARIABLES 显示的变量一样名称,但是有些却不是,有些是在启动参数中设置,有些是必须用 SET 语句更改。而且多个版本中有些参数名称还不一样。 ...
Linux下的Socket编程是一种基础且强大的网络通信方式,用于构建服务器和客户端之间的通信桥梁。本文将通过分析一个简单的Proxy程序来探讨Linux Socket编程的关键概念和技术。 首先,Proxy是一种网络中间件,它允许...
SocketTool提供了用户友好的界面,允许用户设置socket连接的各种参数,如IP地址、端口号、协议类型(TCP或UDP)、超时时间等。此外,工具还可能包含发送和接收数据的选项,以便测试数据传输的正确性和效率。通过模拟...
**参数说明**: - `hostname`: RabbitMQ server所在的主机名。 - `portnumber`: RabbitMQ server监听的端口号,默认为5672。 该函数用于打开到RabbitMQ服务器的socket连接。通过提供主机名和端口号,此函数尝试...
> 升级说明: ----------------- 1、使用 HP-Socket v3.0.1 的应用程序可以安全升级到 HP-Socket v3.0.2 2、由于某些接口方法的参数作了调整,因此请参考测试工程作相应修改 3、如果工程想通过动态链接库方式使用 HP...
注释通常包括功能描述、参数说明、返回值和可能的异常情况,有助于理解Socket编程的细节。 5. **FlawlessCode**:这个文件名可能表示提供的代码是无错误的示例,可以作为模板或参考,帮助开发者快速构建自己的...
### SOCKET编程的小说明 #### 知识点概览 本篇文档主要介绍Socket编程的基本概念、原理以及通过一个具体的示例来展示如何实现基于TCP协议的Socket编程。具体包括: 1. **Socket简介**:解释Socket的概念及其在...
1. **安装与启动**:说明如何下载和安装SocketTool,以及启动程序的方式。 2. **界面介绍**:详细介绍工具的界面布局,包括各个功能区的作用,如服务端配置、客户端配置、日志显示等。 3. **创建服务端**:指导用户...
在提供的压缩包中,"说明.txt"可能包含了关于如何使用这些代码的指南,而"ECode"可能是包含实际C#代码的文件,其中可能包含了实现Socket和串口通信的具体示例。这些代码可以帮助初学者理解并实践这两种通信方式,...
手册中的内容可能会涵盖如何初始化Socket对象,设置连接参数,如何发送和接收数据,以及如何处理网络异常等重要知识点。开发者应该仔细阅读这份手册,以便深入理解框架的内部机制和最佳实践。 在实际应用中,C# ...
socket函数用于创建套接字,AF_INET参数指定了使用的地址族为IPv4,SOCK_STREAM参数指定了使用的协议为TCP。 2. socket函数的使用 在TCPClient.cpp文件中,使用socket函数创建了一个套接字,AF_INET参数指定了...
- **socket函数.txt**: 提供了`socket()`函数的详细解释,可能包括参数说明和返回值。 通过阅读这些文档,你可以深入了解Socket通信的各个方面,并能够使用VS2005开发出自己的Socket通信程序。记住,实践是检验真理...
- **参数说明**: - `domain`:指定了地址族,如AF_INET表示IPv4。 - `type`:指定了Socket类型,如SOCK_STREAM表示流式Socket。 - `protocol`:通常设置为0,表示使用默认协议。 - **返回值**:成功返回一个非负...