精华内容
下载资源
问答
  • By default, Windows 10’s lock screen times out and switches off your monitor after one minute. If you’d like it to stick around longer than that–say, ifyou have background picture you like looking ...
    lst_top

    By default, Windows 10’s lock screen times out and switches off your monitor after one minute. If you’d like it to stick around longer than that–say, if you have background picture you like looking at or you enjoy having Cortana handy–there’s a simple Registry hack that will add the setting to your power options.

    默认情况下,Windows 10的锁定屏幕超时并在一分钟后关闭显示器。 如果您希望它的使用时间更长-例如,如果您有想要观看的背景图片,或者喜欢手持Cortana ,则有一个简单的Registry hack,可以将设置添加到电源选项中。

    First, you’ll need to tackle the Registry to add the timeout setting to your PC’s power options. You can do that by editing the Registry manually or downloading our one-click hacks. After adding the setting, you’ll then set your timeout using the standard Power Options applet in the Control Panel. Here’s how to get it all done.

    首先,您需要解决注册表问题,将超时设置添加到PC的电源选项中。 您可以通过手动编辑注册表或下载我们的一键式技巧来做到这一点。 添加设置后,您将使用“控制面板”中的标准“电源选项”小程序设置超时时间。 这是完成所有工作的方法。

    通过手动编辑注册表将超时设置添加到电源选项 (Add Timeout Setting to Power Options by Editing the Registry Manually)

    To add the timeout setting to power options, you just need to make an adjustment to one setting in the Windows Registry.

    要将超时设置添加到电源选项,您只需要对Windows注册表中的一个设置进行调整。

    Standard warning: Registry Editor is a powerful tool and misusing it can render your system unstable or even inoperable. This is a pretty simple hack and as long as you stick to the instructions, you shouldn’t have any problems. That said, if you’ve never worked with it before, consider reading about how to use the Registry Editor before you get started. And definitely back up the Registry (and your computer!) before making changes.

    标准警告:注册表编辑器是一个功能强大的工具,滥用它会使您的系统不稳定甚至无法运行。 这是一个非常简单的技巧,只要您按照说明进行操作,就不会有任何问题。 也就是说,如果您以前从未使用过它,请在开始之前考虑阅读有关如何使用注册表编辑器的信息。 并在进行更改之前一定要备份注册表(和您的计算机!)。

    Open the Registry Editor by hitting Start and typing “regedit.” Press Enter to open Registry Editor and give it permission to make changes to your PC.

    通过单击开始并键入“ regedit”来打开注册表编辑器。 按Enter键打开注册表编辑器,并授予其对PC进行更改的权限。

    lst_1

    In the Registry Editor, use the left sidebar to navigate to the following key:

    在注册表编辑器中,使用左侧边栏导航至以下键:

    HKEYLOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\7516b95f-f776-4464-8c53-06167f40cc99\8EC4B3A5-6868-48c2-BE75-4F3044BE88A7
    
    lst_2

    In the right-hand pane, double-click the Attributes value to open its properties window.

    在右侧窗格中,双击“ Attributes值以打开其属性窗口。

    lst_3

    Change the value in the “Value data” box from 1 to 2, and then click OK.

    将“数值数据”框中的值从1更改为2,然后单击“确定”。

    lst_4

    That’s all you have to do in the Registry. Your next step will be changing the timeout setting using Power Options. Should you ever want to remove that setting from Power Options, just go back and change the Attributes value from 2 back to 1.

    这就是您在注册表中要做的所有事情。 下一步将使用“电源选项”更改超时设置。 如果您想从“电源选项”中删除该设置,只需返回并将“ Attributes值从2更改为1。

    下载我们的一键式Hack (Download Our One-Click Hack)

    lst_5

    If you don’t feel like diving into the Registry yourself, we’ve created some a couple of registry hacks you can use. The “Add Lock Screen Timeout Setting to Power Options” hack creates the changes the Attributes value from 1 to 2. The “Remove Lock Screen Timeout Setting from Power Options (Default)” hack changes the Attributes value from 2 back to 1, restoring its default setting. Both hacks are included in the following ZIP file. Double-click the one you want to use and click through the prompts. When you’ve applied the hack you want, the changes will take place immediately.

    如果您不想自己进入注册表,我们已经创建了一些可以使用的注册表黑客。 “将锁定屏幕超时设置添加到电源选项” hack将Attributes值从1更改为2。“将锁定屏幕超时设置从电源选项删除(默认)” hack将Attributes值从2更改为1,恢复其Attributes值。默认设置。 这两种黑客都包含在以下ZIP文件中。 双击您要使用的一个,然后单击提示。 应用所需的技巧后, 更改将立即进行。

    Lock Screen Timeout Hacks

    锁屏超时黑客

    These hacks are really just the 8EC4B3A5-6868-48c2-BE75-4F3044BE88A7  key, stripped down to the Attributes value we talked about in the previous section and then exported to a .REG file. Running either of the enable sets that value to the appropriate number. And if you enjoy fiddling with the Registry, it’s worth taking the time to learn how to make your own Registry hacks.

    这些技巧实际上只是8EC4B3A5-6868-48c2-BE75-4F3044BE88A7密钥,被精简为上一节中讨论的“属性”值,然后导出到.REG文件。 运行任何一个启用都会将该值设置为适当的数字。 而且,如果您喜欢使用注册表,则值得花时间学习如何制作自己的注册表黑客

    在电源选项中更改超时设置 (Change the Timeout Setting in Power Options)

    Now that you’ve enabled the timeout setting, it’s time to fire up Power Options and put it to work. Hit Start, type “Power Options,” and then hit Enter to open Power Options.

    现在您已经启用了超时设置,是时候启动电源选项并将其投入使用了。 单击开始,键入“电源选项”,然后按Enter打开电源选项。

    lst_6

    In the Power Options window, click the “Change plan settings” link next to whatever power plan you’re using.

    在“电源选项”窗口中,单击所使用的任何电源计划旁边的“更改计划设置”链接。

    lst_7

    In the Edit Plan Settings window, click the “Change advanced power settings” link.

    在“编辑计划设置”窗口中,单击“更改高级电源设置”链接。

    lst_8

    In the Power Options dialog, expand the “Display” item and you’ll see the new setting you added listed as “Console lock display off timeout.” Expand that and you can then set the timeout for however many minutes you want.

    在“电源选项”对话框中,展开“显示”项,您将看到添加的新设置,列为“控制台锁定显示超时”。 展开它,然后可以将超时设置为所需的分钟数。

    lst_9

    It’s a bit of a hassle having to deal with the Registry just to make this setting available, but at least it’s there. And if you have a desktop PC or a laptop plugged into a power source, it’s nice knowing you can leave that lock screen up for longer than a minute if you want to.

    只是为了使此设置可用而不得不处理注册表有点麻烦,但是至少它存在。 而且,如果您将台式PC或笔记本电脑插入了电源,那么很高兴知道您可以将锁定屏幕停留一分钟以上。

    翻译自: https://www.howtogeek.com/267893/how-to-change-the-windows-10-lock-screen-timeout/

    展开全文
  • WINDOWS环境下设置socket连接超时

    千次阅读 2012-11-09 14:19:53
    众所周知,在进行网络编程的时候,如果使用系统connect函数,无法设置超时,而在连接一个不存在的主机时,将会一直阻塞。 其实在调用connect函数时,将句柄设置为非阻塞,然后调用select函数,可以达到设置超时的...

    众所周知,在进行网络编程的时候,如果使用系统connect函数,无法设置超时,而在连接一个不存在的主机时,将会一直阻塞。

    其实在调用connect函数时,将句柄设置为非阻塞,然后调用select函数,可以达到设置超时的效果。


    1. bool connect(char *host,int port, int timeout)  
    2. {  
    3.     TIMEVAL Timeout;  
    4.     Timeout.tv_sec = timeout;  
    5.     Timeout.tv_usec = 0;  
    6.     struct sockaddr_in address;  /* the libc network address data structure */     
    7.   
    8.     sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
    9.   
    10.     address.sin_addr.s_addr = inet_addr(host); /* assign the address */  
    11.     address.sin_port = htons(port);            /* translate int2port num */  
    12.     address.sin_family = AF_INET;  
    13.   
    14.     //set the socket in non-blocking  
    15.     unsigned long iMode = 1;  
    16.     int iResult = ioctlsocket(sock, FIONBIO, &iMode);  
    17.     if (iResult != NO_ERROR)  
    18.     {  
    19.         printf("ioctlsocket failed with error: %ld\n", iResult);  
    20.     }  
    21.   
    22.     if(connect(sock,(struct sockaddr *)&address,sizeof(address))==false)  
    23.     {  
    24.         return false;  
    25.     }     
    26.   
    27.     // restart the socket mode  
    28.     iMode = 0;  
    29.     iResult = ioctlsocket(sock, FIONBIO, &iMode);  
    30.     if (iResult != NO_ERROR)  
    31.     {  
    32.         printf("ioctlsocket failed with error: %ld\n", iResult);  
    33.     }  
    34.   
    35.     fd_set Write, Err;  
    36.     FD_ZERO(&Write);  
    37.     FD_ZERO(&Err);  
    38.     FD_SET(sock, &Write);  
    39.     FD_SET(sock, &Err);  
    40.   
    41.     // check if the socket is ready  
    42.     select(0,NULL,&Write,&Err,&Timeout);  
    43.     if(FD_ISSET(sock, &Write))  
    44.     {  
    45.         return true;  
    46.     }  
    47.   
    48.     return false;  
    49. }  
    展开全文
  • 关闭防火墙ping请求超时When Windows Firewall is enabled with default settings, you can’t use the ping command from another device to see if your PC is alive. Here’s how to change that. 当使用默认...
    关闭防火墙ping请求超时

    关闭防火墙ping请求超时

    When Windows Firewall is enabled with default settings, you can’t use the ping command from another device to see if your PC is alive. Here’s how to change that.

    当使用默认设置启用Windows防火墙后,您将无法使用其他设备上的ping命令来查看您的PC是否处于活动状态。 更改方法如下。

    The ping command works by sending special packets known as Internet Control Message Protocol (ICMP) Echo Requests to a target device, and then waiting for that device to send back an ICMP Echo Reply packet. This not only lets you test whether a network-connected device is active, but it also measures the response time and displays that for you, as well. By default, Windows Firewall with Advanced Security blocks ICMP Echo Requests from the network. Sure, you could take the drastic step of disabling the firewall for testing purposes, but a simpler solution is just to create an exception that allows ICMP requests through the firewall. We’re going to show you how to do that both from the Command Prompt and the Windows Firewall with Advanced Security interface. (Note that, if you have an antivirus with a firewall or another type of third-party firewall program installed, you’ll need to open ports in that firewall instead of the built-in Windows Firewall.)

    ping命令通过向目标设备发送称为Internet控制消息协议(ICMP)回显请求的特殊数据包,然后等待该设备发回ICMP Echo Reply数据包来工作。 这不仅使您能够测试联网设备是否处于活动状态,而且还可以测量响应时间并为您显示响应时间。 默认情况下, 具有高级安全性的Windows防火墙会阻止来自网络的ICMP回显请求。 当然,您可以采取激进的步骤来禁用防火墙以进行测试 ,但是更简单的解决方案是创建一个允许ICMP请求通过防火墙的异常。 我们将向您展示如何从命令提示符和具有高级安全性的Windows防火墙界面执行此操作。 (请注意,如果您的防病毒软件安装了防火墙或其他类型的第三方防火墙程序,则需要在该防火墙中打开端口,而不是内置Windows防火墙。)

    The instructions in this article should work for Windows 7, 8, and 10. We’ll point out where there are any major differences.

    本文中的说明应适用于Windows 7、8和10。我们将指出存在主要差异的地方。

    Warning: Creating exceptions and opening ports through your firewall does open up security risks. Allowing ping requests isn’t too big a deal, but it’s usually best to block anything you don’t need.

    警告 :创建例外并通过防火墙打开端口会增加安全风险。 允许ping请求没什么大不了的,但是通常最好阻止不需要的任何东西。

    使用命令提示符允许ping请求 (Allow Ping Requests by Using the Command Prompt)

    The fastest way to create an exception for ping requests is with the Command Prompt. You’ll need to open it with admin privileges. To do so in Windows 8 and 10, press Windows+X and then select “Command Prompt (Admin).” In Windows 7, hit Start and type “command prompt.” Right-click the resulting entry and choose “Run as Administrator.”

    创建ping请求异常的最快方法是使用命令提示符。 您需要使用管理员权限打开它。 为此,请在Windows 8和10中按Windows + X,然后选择“命令提示符(管理员)”。 在Windows 7中,点击“开始”,然后键入“命令提示符”。 右键单击结果条目,然后选择“以管理员身份运行”。

    To enable ping requests, you’re going to create two exceptions to allow traffic through the firewall—one for ICMPv4 requests and one for ICMPv6 requests. To create the ICMPv4 exception, type (or copy and paste) the following command at the prompt and then hit Enter:

    要启用ping请求,您将创建两个例外以允许通过防火墙的流量-一个例外用于ICMPv4请求,另一个例外用于ICMPv6请求。 要创建ICMPv4异常,请在提示符下键入(或复制并粘贴)以下命令,然后按Enter键:

    netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow
    

    And to create the ICMPv6 exception, use this command:

    要创建ICMPv6异常,请使用以下命令:

    netsh advfirewall firewall add rule name="ICMP Allow incoming V6 echo request" protocol=icmpv6:8,any dir=in action=allow
    

    The changes will take place immediately—no need to restart your PC or anything. Now, if you ping your PC from a remote device, you should get an actual result.

    更改将立即进行-无需重新启动PC或任何其他操作。 现在,如果您从远程设备ping PC,您应该会得到实际的结果。

    To disable ping requests again, you’ll need to disable both exceptions you created. For the ICMPv4 exception, type (or copy and paste) this command at the prompt and hit Enter:

    要再次禁用ping请求,您需要禁用创建的两个异常。 对于ICMPv4异常,请在提示符下键入(或复制并粘贴)此命令,然后按Enter:

    netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=block
    

    And to disable ICMPv6 requests, use this command:

    要禁用ICMPv6请求,请使用以下命令:

    netsh advfirewall firewall add rule name="ICMP Allow incoming V6 echo request" protocol=icmpv6:8,any dir=in action=block
    

    When requests are blocked, ping requests to your PC will be met with a “Request timed out” error.

    当请求被阻止时,对PC的ping请求将遇到“请求超时”错误。

    Note that when using the commands we just covered, you can use any name for the rule you want. However, when you go to disable a rule, you’ll want to use the same rule name as when you created it. If you forget the name of the rule, you can use the Command Prompt to see a list of all rules. Just type the following command and hit Enter:

    请注意,在使用我们刚刚介绍的命令时,您可以为所需的规则使用任何名称。 但是,当您禁用规则时,您将要使用与创建规则时相同的规则名称。 如果忘记了规则名称,则可以使用命令提示符查看所有规则的列表。 只需键入以下命令,然后按Enter:

    netsh advfirewall firewall show rule name=all
    

    You’ll see lots of rules listed, but scroll back up to the top of the list and you should see any rules you’ve created right at the top.

    您会看到列出了许多规则,但是向上滚动到列表的顶部,您应该在顶部看到自己创建的任何规则。

    通过使用具有高级安全性的Windows防火墙来允许Ping请求 (Allow Ping Requests by Using Windows Firewall With Advanced Security)

    While the Command Prompt is the quickest way to add an exception to your firewall for ping requests, you can also do this in the graphic interface using the “Windows Firewall with Advanced Security” app. Hit Start, type “windows firewall with,” and then launch “Windows Firewall with Advanced Security.”

    虽然命令提示符是向防火墙添加ping请求例外的最快方法,但是您也可以使用“具有高级安全性的Windows防火墙”应用程序在图形界面中执行此操作。 单击开始,键入“ Windows防火墙使用”,然后启动“具有高级安全性的Windows防火墙”。

    You’re going to create two new rules—one for allowing ICMPv4 requests and one for allowing ICMPv6 requests. In the left pane, right-click “Inbound Rules” and choose “New Rule.”

    您将创建两个新规则-一个用于允许ICMPv4请求的规则,另一个用于允许ICMPv6请求的规则。 在左窗格中,右键单击“入站规则”,然后选择“新规则”。

    In the “New Inbound Rule Wizard” window, select “Custom” and then click “Next.”

    在“新建入站规则向导”窗口中,选择“自定义”,然后单击“下一步”。

    On the next page, make sure “All programs” is selected and then click “Next.”

    在下一页上,确保选中“所有程序”,然后单击“下一步”。

    On the next page, choose “ICMPv4” from the “Protocol type” dropdown and then click the “Customize” button.

    在下一页上,从“协议类型”下拉列表中选择“ ICMPv4”,然后单击“自定义”按钮。

    In the “Customize ICMP Settings” window, select the “Specific ICMP types” option. In the list of ICMP types, enable “Echo Request” and then click “OK.”

    在“自定义ICMP设置”窗口中,选择“特定ICMP类型”选项。 在ICMP类型列表中,启用“回显请求”,然后单击“确定”。

    Back in the “New Inbound Rule Wizard” window, you’re ready to click “Next.”

    返回“新建入站规则向导”窗口,您可以单击“下一步”。

    On the next page, it’s easiest to just make sure that the “Any IP address” options are selected for both local and remote IP addresses. If you want, you can configure specific IP addresses to which your PC will respond to a ping request. Other ping requests are ignored. This lets you narrow things down a bit so that only certain devices will be able to ping your PC. You can also configure separate lists of approved IP addresses for your local and remote (Internet) networks. However you set it up, click “Next” when you’re done.

    在下一页上,最简单的方法是确保为本地和远程IP地址都选择了“任何IP地址”选项。 如果需要,您可以配置PC响应ping请求的特定IP地址。 其他ping请求将被忽略。 这使您可以缩小范围,以便仅某些设备能够ping您的PC。 您也可以为本地和远程(Internet)网络配置单独的认可IP地址列表。 但是,设置完成后,请单击“下一步”。

    On the next page, make sure that the “Allow the connection” option is enabled and then click “Next.”

    在下一页上,确保启用“允许连接”选项,然后单击“下一步”。

    The next page allows you some control over when the rule is active. If you want the rule to apply no matter what type of network it’s connected to, leave the options at their default and just click “Next.” However, if your PC is not part of a business (and doesn’t connect to a domain), or if you prefer it not respond to ping requests when it’s connected to a public network, feel free to disable those options.

    下一页允许您控制何时激活规则。 如果您希望该规则无论连接到哪种类型的网络都适用,请将这些选项保留为默认值,然后单击“下一步”。 但是,如果您的PC不属于企业(并且未连接到域),或者如果您希望PC在连接到公共网络时不响应ping请求,请随时禁用这些选项。

    Finally, you need to give your new rule a name, and optionally a description. However, we do recommend that you at least get the text “ICMPv4” in there because you’ll also be creating a second rule for allowing ICMPv6 requests. Choose whatever makes sense to you and then click “Finish.”

    最后,您需要给新规则起一个名字,以及一个可选的描述。 但是,我们建议您至少在其中输入文本“ ICMPv4”,因为您还将创建第二条规则来允许ICMPv6请求。 选择对您有意义的任何内容,然后单击“完成”。

    Unfortunately, you’re not quite done yet. It’s a good idea to go ahead and create a second rule that allows incoming ICMPv6 requests. Mostly, it’s a good just-in-case measure. People tend to use IPv4 addresses when issuing ping commands, but some networking apps use IPv6. Might as well have your bases covered.

    不幸的是,您还没有完成。 继续创建允许传入ICMPv6请求的第二条规则是一个好主意。 通常,这是一个很好的案例。 人们在发出ping命令时倾向于使用IPv4地址,但是某些网络应用程序使用IPv6。 可能还包括您的基地。

    Follow the same steps we just went over and set all the options exactly the same as we did for the ICMPv4 rule. However, when you get to the ports and protocols page, select “ICMPv6” from the dropdown instead of “ICMPv4.” That—and creating a different name for the rule—are the only two things that change.

    遵循我们刚刚经过的相同步骤,并将所有选项设置为与对ICMPv4规则完全相同的设置。 但是,当您进入端口和协议页面时,请从下拉列表中选择“ ICMPv6”,而不是“ ICMPv4”。 唯一的两件事就是更改,并为规则创建一个不同的名称。

    When you have the two new rules in place, you can close the “Windows Firewall with Advanced Security” app. No need to restart your PC or anything. Your PC should immediately begin responding to pings.

    有了两个新规则后,您可以关闭“具有高级安全性的Windows防火墙”应用程序。 无需重启PC或其他任何操作。 您的PC应该立即开始响应ping。

    If you ever want to disable all this, you could go back and delete those two rules. However, you might be better off just disabling the rules instead. That way, you can re-enable them without recreating them. In the “Windows Firewall with Advanced Security” app, select “Inbound Rules” on the left, and locate the rules you made in the middle pane. Right-click a rule and choose “Disable” to prevent ping requests from passing through the firewall.

    如果您想禁用所有这些功能,则可以返回并删除这两个规则。 但是,最好禁用这些规则。 这样,您可以重新启用它们而无需重新创建它们。 在“具有高级安全性的Windows防火墙”应用中,选择左侧的“入站规则”,然后在中间窗格中找到您制定的规则。 右键单击规则,然后选择“禁用”,以防止ping请求通过防火墙。

    Allowing ping requests to reach your PC is not something everyone will need to do. But, if you’re doing any kind of network troubleshooting, ping can be a valuable tool. It’s also pretty easy to turn on and off once you have things set up.

    每个人都不需要允许ping请求到达您的PC。 但是,如果您要进行任何类型的网络故障排除,则ping可能是一个有价值的工具。 设置完所有东西后,打开和关闭它也很容易。

    翻译自: https://www.howtogeek.com/howto/windows-vista/allow-pings-icmp-echo-request-through-your-windows-vista-firewall/

    关闭防火墙ping请求超时

    展开全文
  • TCP定时器之超时重传定时器

    千次阅读 2019-03-09 12:26:24
    每条TCP连接都会维护一个超时重传定时器,该定时器是TCP保证可靠性的一个非常重要的手段,一旦该定时器超时,那么就会重传还未收到ACK的报文。这篇笔记就来看看该定时器相关的代码实现。 1. 相关数据结构 struct ...

    每条TCP连接都会维护一个超时重传定时器,该定时器是TCP保证可靠性的一个非常重要的手段,一旦该定时器超时,那么就会重传还未收到ACK的报文。这篇笔记就来看看该定时器相关的代码实现。

    1. 相关数据结构

    struct inet_connection_sock {
    ...
    	//icsk_retransmit_timer的超时时刻,jiffies超过该值时定时器超时
    	unsigned long		  icsk_timeout;
    	//超时重传定时器、持续定时器(还有其它)
     	struct timer_list	  icsk_retransmit_timer;
    ...
    	//拥塞状态
    	__u8			  icsk_ca_state;
    	//发生超时重传的次数。当退出LOSS状态时该计数器清零
    	__u8			  icsk_retransmits;
    	//icsk_retransmit_timer定时器函数可以处理4个定时器,
    	//当前应该处理哪个事件也需要区分,0表示没有事件需要处理
    	__u8			  icsk_pending;
    ...
    };
    

    2. 初始化

    超时重传定时器是在socket()系统调用执行过程中初始化的,具体在创建TCB后调用tcp_v4_sock_init()初始化其TCP相关字段时完成的,代码如下:

    static int tcp_v4_init_sock(struct sock *sk)
    {
    ...
    	tcp_init_xmit_timers(sk);
    ...
    }
    
    void tcp_init_xmit_timers(struct sock *sk)
    {
    	//超时重传定时器的定时器处理函数为tcp_write_time()
    	inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer,
    				  &tcp_keepalive_timer);
    }
    
    /*
     * Using different timers for retransmit, delayed acks and probes
     * We may wish use just one timer maintaining a list of expire jiffies
     * to optimize.
     */
    //该函数安装三个定时器
    void inet_csk_init_xmit_timers(struct sock *sk,
    			       void (*retransmit_handler)(unsigned long),
    			       void (*delack_handler)(unsigned long),
    			       void (*keepalive_handler)(unsigned long))
    {
    	struct inet_connection_sock *icsk = inet_csk(sk);
    
    	setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler,
    			(unsigned long)sk);
    	setup_timer(&icsk->icsk_delack_timer, delack_handler,
    			(unsigned long)sk);
    	setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk);
    	//由于同一个定时器函数可以处理多个定时器,它们也需要进行区分,pending参数表示
    	//当前需要处理的是哪个定时事件,0表示没有事件需要处理
    	icsk->icsk_pending = icsk->icsk_ack.pending = 0;
    }
    
    //setup_timer()仅仅是初始化定时器参数,并没有启动定时器
    static inline void setup_timer(struct timer_list * timer,
    				void (*function)(unsigned long),
    				unsigned long data)
    {
    	timer->function = function;
    	//data参数就是TCB指针
    	timer->data = data;
    	init_timer(timer);
    }
    

    3. 启动定时器

    启动定时器由函数inet_csk_reset_xmit_timer()完成。

    /*
     *	Reset the retransmission timer
     */
    @what: 表示要复位的定时器,对于超时重传定时器,该值为ICSK_TIME_RETRANS;
    @when: 表示该定时器再过几个滴答超时;
    @max_when: when可取的最大值,如果指定when超过了max_when,那么只取max_when.
    static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what,
    					     unsigned long when,
    					     const unsigned long max_when)
    {
    	struct inet_connection_sock *icsk = inet_csk(sk);
    
    	//矫正when参数
    	if (when > max_when) {
    		when = max_when;
    	}
    	//关注what为ICSK_TIME_RETRANS的情况
    	if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
    		//将事件记录到icsk_pending中表示启动的定时器是超时重传定时器
    		icsk->icsk_pending = what;
    		//记录超时时间点到icsk_timeout
    		icsk->icsk_timeout = jiffies + when;
    		//重新启动定时器
    		sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
    	} else if (what == ICSK_TIME_DACK) {
    		icsk->icsk_ack.pending |= ICSK_ACK_TIMER;
    		icsk->icsk_ack.timeout = jiffies + when;
    		sk_reset_timer(sk, &icsk->icsk_delack_timer, icsk->icsk_ack.timeout);
    	}
    }
    
    void sk_reset_timer(struct sock *sk, struct timer_list* timer,
    		    unsigned long expires)
    {
    	//定时器启动期间会持有TCB的引用,防止其被释放
    	if (!mod_timer(timer, expires))
    		sock_hold(sk);
    }
    
    

    3.1 启动时机

    超时重传定时器会在如下几种情况下激活:

    1. 发送了第一包新数据(第一次发送或者之间发送的已经全部被确认);
    2. 路径MTU探测失败后;
    3. 发现接收端将SACK确认过的数据丢掉后。

    4. 超时处理

    RTO超时后,由定时器函数tcp_write_timer()开始处理.

    在整个超时处理过程中,当前只关注连接态的处理。

    4.1 tcp_write_timer()

    static void tcp_write_timer(unsigned long data)
    {
    	struct sock *sk = (struct sock*)data;
    	struct inet_connection_sock *icsk = inet_csk(sk);
    	int event;
    
    	//定时器函数在软中断中执行,这里先锁定套接字
    	bh_lock_sock(sk);
    
    	//如果TCB被进程上下文锁定,那么推后50ms再尝试
    	if (sock_owned_by_user(sk)) {
    		sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + (HZ / 20));
    		goto out_unlock;
    	}
    	//如果套接字已经关闭或者定时器根本就没有启动,退出
    	if (sk->sk_state == TCP_CLOSE || !icsk->icsk_pending)
    		goto out;
    	//如果没有超时,重新设定超时时间
    	if (time_after(icsk->icsk_timeout, jiffies)) {
    		sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
    		goto out;
    	}
    	//以上都是一些保护性的检查
    
    	event = icsk->icsk_pending;
    	//即将处理事件,将icsk_pending置为0,表示清除事件,后面如果需要会重新设定
    	icsk->icsk_pending = 0;
    	switch (event) {
    	case ICSK_TIME_RETRANS:
    		//超时重传有该函数处理
    		tcp_retransmit_timer(sk);
    		break;
    	case ICSK_TIME_PROBE0:
    		tcp_probe_timer(sk);
    		break;
    	}
    	TCP_CHECK_TIMER(sk);
    
    out:
    	//内存回收
    	sk_mem_reclaim(sk);
    out_unlock:
    	bh_unlock_sock(sk);
    	sock_put(sk);
    }
    

    4.2 超时重传事件处理tcp_retransmit_timer()

    /*
     *	The TCP retransmit timer.
     */
    static void tcp_retransmit_timer(struct sock *sk)
    {
    	struct tcp_sock *tp = tcp_sk(sk);
    	struct inet_connection_sock *icsk = inet_csk(sk);
    
    	//如果根本就没有发送数据何来超时处理。保护性检查
    	if (!tp->packets_out)
    		goto out;
    	//同上,发送队列是空的
    	BUG_TRAP(!tcp_write_queue_empty(sk));
    
    	//发送窗口为0;socket没有关闭;当前不再三次握手阶段(说明在连接态)。
    	//这种情况下发生了超时,需要检查是否需要关闭套接字
    	if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) &&
    	    !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) {
    		/* Receiver dastardly shrinks window. Our retransmits
    		 * become zero probes, but we should not timeout this
    		 * connection. If the socket is an orphan, time it out,
    		 * we cannot allow such beasts to hang infinitely.
    		 */
    		//如果这条连接上已经有很长时间(超过TCP_RTO_MAX=120s)没有收到对端
    		//的确认了,认为连接异常了,直接关闭该套接字
    		if (tcp_time_stamp - tp->rcv_tstamp > TCP_RTO_MAX) {
    			tcp_write_err(sk);
    			goto out;
    		}
    		//这种情况说明对方已经很拥塞了,进入LOSS状态
    		tcp_enter_loss(sk, 0);
    		//重传第一包数据
    		tcp_retransmit_skb(sk, tcp_write_queue_head(sk));
    		//清理路由,因为路由可能也是有问题的
    		__sk_dst_reset(sk);
    		goto out_reset_timer;
    	}
    
    	//超时重传也不能无限重传下去,必须有截止时间,该函数判断是否继续执行超时重传
    	if (tcp_write_timeout(sk))
    		goto out;
    
    	//如果是第一次超时重传
    	if (icsk->icsk_retransmits == 0) {
    		if (icsk->icsk_ca_state == TCP_CA_Disorder ||
    		    icsk->icsk_ca_state == TCP_CA_Recovery) {
    			if (tcp_is_sack(tp)) {
    				if (icsk->icsk_ca_state == TCP_CA_Recovery)
    					NET_INC_STATS_BH(LINUX_MIB_TCPSACKRECOVERYFAIL);
    				else
    					NET_INC_STATS_BH(LINUX_MIB_TCPSACKFAILURES);
    			} else {
    				if (icsk->icsk_ca_state == TCP_CA_Recovery)
    					NET_INC_STATS_BH(LINUX_MIB_TCPRENORECOVERYFAIL);
    				else
    					NET_INC_STATS_BH(LINUX_MIB_TCPRENOFAILURES);
    			}
    		} else if (icsk->icsk_ca_state == TCP_CA_Loss) {
    			NET_INC_STATS_BH(LINUX_MIB_TCPLOSSFAILURES);
    		} else {
    			NET_INC_STATS_BH(LINUX_MIB_TCPTIMEOUTS);
    		}
    	}
    
    	//暂时不考虑F-RTO算法,走else分支,切换拥塞状态为LOSS
    	if (tcp_use_frto(sk)) {
    		tcp_enter_frto(sk);
    	} else {
    		tcp_enter_loss(sk, 0);
    	}
    	//尝试重传第一包数据,如果发送失败说明本地发生了拥塞,这时不执行指数退避
    	if (tcp_retransmit_skb(sk, tcp_write_queue_head(sk)) > 0) {
    		/* Retransmission failed because of local congestion,
    		 * do not backoff.
    		 */
    		if (!icsk->icsk_retransmits)
    			icsk->icsk_retransmits = 1;
    		//重启超时重传定时器,超时时间为当前RTO和500ms(本地资源探测间隔)中的最小值
    		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
    					  min(icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL),
    					  TCP_RTO_MAX);
    		goto out;
    	}
    
    	/* Increase the timeout each time we retransmit.  Note that
    	 * we do not increase the rtt estimate.  rto is initialized
    	 * from rtt, but increases here.  Jacobson (SIGCOMM 88) suggests
    	 * that doubling rto each time is the least we can get away with.
    	 * In KA9Q, Karn uses this for the first few times, and then
    	 * goes to quadratic.  netBSD doubles, but only goes up to *64,
    	 * and clamps at 1 to 64 sec afterwards.  Note that 120 sec is
    	 * defined in the protocol as the maximum possible RTT.  I guess
    	 * we'll have to use something other than TCP to talk to the
    	 * University of Mars.
    	 *
    	 * PAWS allows us longer timeouts and large windows, so once
    	 * implemented ftp to mars will work nicely. We will have to fix
    	 * the 120 second clamps though!
    	 */
    	//累加指数退避次数和发生超时重传次数
    	icsk->icsk_backoff++;
    	icsk->icsk_retransmits++;
    
    out_reset_timer:
    	//执行指数退避算法,更新下次超时间隔记录到icsk_rto
    	icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
    	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
    	if (icsk->icsk_retransmits > sysctl_tcp_retries1)
    		__sk_dst_reset(sk);
    
    out:;
    }
    

    小结一下:从上面可以看出,超时重传的处理逻辑还是很清晰的。1)首先检查是否还允许继续进行超时重传,这时综合考虑最大重传次数限制、系统拥塞限制、socket状态等因素;2)一旦允许超时重传,那么只重发当前发送队列中的第一个包,然后按照指数退避算法重启定时器。

    4.2.1 重传超时截止判断tcp_write_timeout()

    /* A write timeout has occurred. Process the after effects. */
    static int tcp_write_timeout(struct sock *sk)
    {
    	struct inet_connection_sock *icsk = inet_csk(sk);
    	//retry_until记录最多可以发生多少次超时重传
    	int retry_until;
    
    	//SYN段的重传超时截止判定
    	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
    		if (icsk->icsk_retransmits)
    			dst_negative_advice(&sk->sk_dst_cache);
    		retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
    	} else {
    		//对于非SYN段,如果超时重传次数超过了门限sysctl_tcp_retries1,
    		//那么尝试做MTU探测和重新路由选择
    		if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
    			/* Black hole detection */
    			tcp_mtu_probing(icsk, sk);
    			dst_negative_advice(&sk->sk_dst_cache);
    		}
    		//允许的最大重传次数由系统参数sysctl_tcp_retries2决定
    		retry_until = sysctl_tcp_retries2;
    		//如果socket设置了DEAD标记,那么这种socket叫做“孤儿socket”,
    		//此时需要检查这种socket是否超过了系统限制,如果超过那么也不再继续重传
    		if (sock_flag(sk, SOCK_DEAD)) {
    			//如果该socket的RTO还没有超过最大RTO 120s,那么认为它还是存活的,
    			//即认为其有可能是可以按照正常流程终止的,后面会尽可能的进行重传
    			const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
    			//根据alive标记判断允许该socket重传的最大次数
    			retry_until = tcp_orphan_retries(sk, alive);
    			//如果孤儿socket超过了指定数目限制,并且系统资源吃紧,那么会关闭该socket;
    			//如果该socket还不至于彻底死掉,那么为了让对端感知关闭,也会发送RST
    			if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
    				return 1;
    		}
    	}
    	//如果最终超时重传次数超过了最大允许次数,关闭socket,这会向应用程序返回-1(ETIMEOUT)
    	if (icsk->icsk_retransmits >= retry_until) {
    		/* Has it gone just too far? */
    		tcp_write_err(sk);
    		return 1;
    	}
    	return 0;
    }
    

    4.2.2 孤儿socket最大重传次数判定tcp_orphan_retries()

    /* Calculate maximal number or retries on an orphaned socket. */
    static int tcp_orphan_retries(struct sock *sk, int alive)
    {
    	//孤儿socket默认取系统允许的最大重传次数
    	int retries = sysctl_tcp_orphan_retries; /* May be zero. */
    
    	//该socket已经明确的检测到了错误,并且RTO已经超过了TCP_RTO_MAX,
    	//没有必要继续重试了,返回0次
    	if (sk->sk_err_soft && !alive)
    		retries = 0;
    
    	/* However, if socket sent something recently, select some safe
    	 * number of retries. 8 corresponds to >100 seconds with minimal
    	 * RTO of 200msec. */
    	//socket还可以保留,并且系统没有配置sysctl_tcp_orphan_retries的情况下设置为8次
    	if (retries == 0 && alive)
    		retries = 8;
    	return retries;
    }
    

    4.2.3 孤儿socket资源消耗判定tcp_out_of_resources()

    为了防止系统出现过多的孤儿socket吃光系统资源,TCP会及时的清理这些socket。

    /* Do not allow orphaned sockets to eat all our resources.
     * This is direct violation of TCP specs, but it is required
     * to prevent DoS attacks. It is called when a retransmission timeout
     * or zero probe timeout occurs on orphaned socket.
     *
     * Criteria is still not confirmed experimentally and may change.
     * We kill the socket, if:
     * 1. If number of orphaned sockets exceeds an administratively configured
     *    limit.
     * 2. If we have strong memory pressure.
     */
    static int tcp_out_of_resources(struct sock *sk, int do_reset)
    {
    	struct tcp_sock *tp = tcp_sk(sk);
    	//全局变量tcp_orphan_count记录了当前系统有多少个孤儿进程
    	int orphans = atomic_read(&tcp_orphan_count);
    
    	/* If peer does not open window for long time, or did not transmit
    	 * anything for long time, penalize it. */
    	//如果确实已经很长时间没有发送数据了,那么惩罚一下,把orphans扩大一倍,
    	//使其更容易使tcp_too_many_orphans()成立
    	if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset)
    		orphans <<= 1;
    
    	//同上,如果有软件错误,也惩罚
    	if (sk->sk_err_soft)
    		orphans <<= 1;
    
    	//判断是否该socket是否需要关闭。就是基于系统参数和当前socket的内存占用情况
    	if (tcp_too_many_orphans(sk, orphans)) {
    		if (net_ratelimit())
    			printk(KERN_INFO "Out of socket memory\n");
    
    		/* Catch exceptional cases, when connection requires reset.
    		 *      1. Last segment was sent recently. */
    		if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
    		    /*  2. Window is closed. */
    		    (!tp->snd_wnd && !tp->packets_out))
    			do_reset = 1;
    		//向对端发送RST报文
    		if (do_reset)
    			tcp_send_active_reset(sk, GFP_ATOMIC);
    		//关闭该孤儿socket
    		tcp_done(sk);
    		NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY);
    		return 1;
    	}
    	return 0;
    }
    
    static inline int tcp_too_many_orphans(struct sock *sk, int num)
    {
    	return (num > sysctl_tcp_max_orphans) ||
    		(sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
    		 atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
    }
    

    5. 数据包重传tcp_retransmit_skb()

    其实无论是超时重传还是快速重传,都是通过调用该函数实现的,每调用一次该函数尝试发送一个skb,如果成功发送出去(只是递交给了底层),该函数返回0,否则返回错误码。

    /* This retransmits one SKB.  Policy decisions and retransmit queue
     * state updates are done by the caller.  Returns non-zero if an
     * error occurred which prevented the send.
     */
    int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
    {
    	struct tcp_sock *tp = tcp_sk(sk);
    	struct inet_connection_sock *icsk = inet_csk(sk);
    	unsigned int cur_mss = tcp_current_mss(sk, 0);
    	int err;
    
    	/* Inconslusive MTU probe */
    	if (icsk->icsk_mtup.probe_size) {
    		icsk->icsk_mtup.probe_size = 0;
    	}
    
    	/* Do not sent more than we queued. 1/4 is reserved for possible
    	 * copying overhead: fragmentation, tunneling, mangling etc.
    	 */
    	//因为重传时要克隆skb头部,需要内存分配,所以先检查内存使用情况
    	if (atomic_read(&sk->sk_wmem_alloc) >
    	    min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
    		return -EAGAIN;
    	//如果skb的前半部分已经确认过了,那么需要拆分该skb
    	if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
    		//如果发现后半部分也已经确认过了,还是让重传,出BUG了
    		if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
    			BUG();
    		//将skb头部的指定字节数删除,这部分数据是已经确认过的
    		if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
    			return -ENOMEM;
    	}
    
    	/* If receiver has shrunk his window, and skb is out of
    	 * new window, do not retransmit it. The exception is the
    	 * case, when window is shrunk to zero. In this case
    	 * our retransmit serves as a zero window probe.
    	 */
    	//发送窗口不允许重传
    	if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))
    	    && TCP_SKB_CB(skb)->seq != tp->snd_una)
    		return -EAGAIN;
    
    	//如果skb长度超过了MSS,那么拆分该skb。这时可以发现,如果使用了TSO,
    	//原来skb中保存了很多个段,一旦该skb需要重传,那么只能发送一个段,还
    	//需要进行skb的拆封
    	if (skb->len > cur_mss) {
    		if (tcp_fragment(sk, skb, cur_mss, cur_mss))
    			return -ENOMEM; /* We'll try again later. */
    	}
    
    	/* Collapse two adjacent packets if worthwhile and we can. */
    	//额...,为了兼容某些打印机,和系统参数sysctl_tcp_retrans_collapse相关,尝试合并skb
    	if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&
    	    (skb->len < (cur_mss >> 1)) &&
    	    (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
    	    (!tcp_skb_is_last(sk, skb)) &&
    	    (skb_shinfo(skb)->nr_frags == 0 &&
    	     skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) &&
    	    (tcp_skb_pcount(skb) == 1 &&
    	     tcp_skb_pcount(tcp_write_queue_next(sk, skb)) == 1) &&
    	    (sysctl_tcp_retrans_collapse != 0))
    		tcp_retrans_try_collapse(sk, skb, cur_mss);
    	//重新进行路由查询,具体见inet_sk_rebuild_header()
    	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
    		return -EHOSTUNREACH; /* Routing failure or similar. */
    
    	/* Some Solaris stacks overoptimize and ignore the FIN on a
    	 * retransmit when old data is attached.  So strip it off
    	 * since it is cheap to do so and saves bytes on the network.
    	 */
    	if (skb->len > 0 && (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
    	    tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
    		if (!pskb_trim(skb, 0)) {
    			/* Reuse, even though it does some unnecessary work */
    			tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1, TCP_SKB_CB(skb)->flags);
    			skb->ip_summed = CHECKSUM_NONE;
    		}
    	}
    
    	/* Make a copy, if the first transmission SKB clone we made
    	 * is still in somebody's hands, else make a clone.
    	 */
    	//记录该skb的发送时间,这里可以看出,重传时skb的when是会更新的
    	TCP_SKB_CB(skb)->when = tcp_time_stamp;
    	//发送该skb,第三个参数表示要克隆skb头部
    	err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
    	//如果发送成功,更新重传相关的统计量
    	if (err == 0) {
    		/* Update global TCP statistics. */
    		TCP_INC_STATS(TCP_MIB_RETRANSSEGS);
    		//累加总的重传次数
    		tp->total_retrans++;
    		//如果之前[snd_una, snd_nxt)之间还没有数据包发生重传,那么
    		//这是第一个,将发送重传时的snd_nxt记录到lost_retrans_low
    		//中,用于拥塞控制算法中Recovery和LOSS状态的退出
    		if (!tp->retrans_out)
    			tp->lost_retrans_low = tp->snd_nxt;
    		//该skb的记分牌中打上重传标记,表示其发生过了重传
    		TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;
    		//累加重传的段数
    		tp->retrans_out += tcp_skb_pcount(skb);
    
    		/* Save stamp of the first retransmit. */
    		//retrans_stamp记录了第一次发生重传的时间。当收到的ACK确认了新数据或者
    		//retrans_out重新变为0时该值会被重新设置为0
    		if (!tp->retrans_stamp)
    			tp->retrans_stamp = TCP_SKB_CB(skb)->when;
    
    		tp->undo_retrans++;
    		/* snd_nxt is stored to detect loss of retransmitted segment,
    		 * see tcp_input.c tcp_sacktag_write_queue().
    		 */
    		//对于重传段,该ack_seq已经不是其本身的含义了,而是记录了重传该段时的snd_nxt
    		TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
    	}
    	return err;
    }
    

    6. 系统参数

    sysctl_tcp_retries1(INTEGER)

    对应系统目录/proc/sys/net/ipv4/tcp_retries1,原生文档的解释为:This value influences the time, after which TCP decides, that something is wrong due to unacknowledged RTO retransmissions, and reports this suspicion to the network layer. See tcp_retries2 for more details.

    RFC 1122 recommends at least 3 retransmissions, which is the default.

    也就是说当TCP处于连接态时,该参数决定了TCP应该在RTO连续发生几次后将这一错误报告给网络层。从上面的代码实现中可以看到,linux的实现是进行PMTU探测和重新进行路由选择。

    sysctl_tcp_retries2(INTEGER)

    对应系统目录/proc/sys/net/ipv4/tcp_retries2,原生文档的解释为:This value influences the timeout of an alive TCP connection, when RTO retransmissions remain unacknowledged. Given a value of N, a hypothetical TCP connection following exponential backoff with an initial RTO of TCP_RTO_MIN would retransmit N times before killing the connection at the (N+1)th RTO.

    The default value of 15 yields a hypothetical timeout of 924.6 seconds and is a lower bound for the effective timeout. TCP will effectively time out at the first RTO which exceeds the hypothetical timeout.

    RFC 1122 recommends at least 100 seconds for the timeout, which corresponds to a value of at least 8.

    意思就是当RTO超过指定次数后就不再重传,而是放弃该TCP连接。

    sysctl_tcp_orphan_retries(INTEGER)

    对应系统目录/proc/sys/net/ipv4/tcp_orphan_retries,原生文档的解释为: This value influences the timeout of a locally closed TCP connection, when RTO retransmissions remain unacknowledged. See tcp_retries2 for more details.

    The default value is 8. If your machine is a loaded WEB server, you should think about lowering this value, such sockets may consume significant resources. Cf. tcp_max_orphans.

    意思就是对于本地已经关闭的socket(对应代码中设置了DEAD标记),还需要经历多少次超时重传,这样的socket会消耗系统资源。

    sysctl_tcp_max_orphans(INTEGER)

    对应系统目录/proc/sys/net/ipv4/tcp_max_orphans,原生文档的解释为: Maximal number of TCP sockets not attached to any user file handle, held by system. If this number is exceeded orphaned connections are reset immediately and warning is printed. This limit exists only to prevent simple DoS attacks, you must not rely on this or lower the limit artificially, but rather increase it(probably, after increasing installed memory), if network conditions require more than default value, and tune network services to linger and kill such states more aggressively. Let me to remind again: each orphan eats up to ~64K of unswappable memory.

    意思就是孤儿socket会消耗系统内存,所以不应该存在过多,通过该值可以简单的限定它们的数量。

    sysctl_tcp_retrans_collapse(BOOLEAN)

    对应系统目录/proc/sys/net/ipv4/tcp_retrans_collapse,原生文档的描述为:Bug-to-bug compatibility with some broken printers. On retransmit try to send bigger packets to work around bugs in certain TCP stacks.

    7. 参考

    1. kernel原生系统参数文档
    2. TCP数据发送之发送新数
    展开全文
  • TCP超时重传定时器梳理

    千次阅读 2017-10-14 15:32:32
    超时重传定时器是TCP连接可靠性的重要保证,其工作原理为TCP连接在发送某一个数据报文或者SYN报文后,该连接就会启动一个定时器,在规定时间内如果没有收到对端回复的ACK报文,那么定时器超时处理函数就重新发送数据...
  • Windows API (包含了所有Windows API)

    千次阅读 2016-02-18 21:57:46
    Windows API (包含了所有Windows API)Api函数名 函数说明 WIN16可用 WIN95可用 WINNT可用-------------------------------------------------------------------------
  • linux TCP超时重传

    万次阅读 2013-06-04 11:16:48
    TCP超时重传是保证TCP可靠性传输的机制之一,当超时后仍没有收到应答报文,就重传数据包并设置超时时钟(超时时间一般增大到原超时时间2倍);直到收到应答报文或超过最大重试次数。 linux TCP超时重传是通过设置...
  • sql 查询超时已过期 SQL Server provides you with a good solution to automate a lot of your administrative tasks using the SQL Server Agent jobs. These jobs are handled from the operating system side ...
  • autodesk CAD2020许可检出超时

    万次阅读 2019-05-05 09:12:12
    笔记本电脑系统为windows7,系统休眠后没有正常恢复系统,之后使用cad2020提示“许可检出超时”,开始通过重新安装cad软件可以正常使用,但休眠后cad还是会出现同样的提示。查询CAD官方支持文档发现可能是“混合睡眠...
  • FTP被动模式连接及超时问题解决

    万次阅读 2015-05-20 17:48:33
    2、连接FTP服务器,长时间进行数据操作时,超时自动断开。 分析: 1、因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。 2、ftp的端口号20...
  • 浏览器刷新及设置注册表超时时间

    千次阅读 2015-08-26 18:22:14
    浏览器的连接超时 ...1,打开注册表:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings。 2,增加一个DWORD值的项,命名为ReceiveTimeout,设置1000。该值的默认单位是毫秒,这里设
  • 在windous系统下Python实现海康相机登入、预览、抓图、光学变倍、相机激活、区域聚焦、区域曝光功能;linux系统下载相应的海康SDK,并将lib文件更换为相对应的库文件,同时将HCNetSDKCom文件夹拷贝出来(与lib文件夹...
  • 解决多版本同时存在的pip安装模块 ...当安装模块超时时可以通过修改超时时间的方式来进行解决,也可以通过修改安装源的方式解决。 修改超时时间 pip --default-timeout=100 install numpy 通...
  • 如何设置socket的Connect超时

    千次阅读 2014-10-16 22:28:53
    如何设置socket的Connect超时 1.首先将标志位设为Non-blocking模式,准备在非阻塞模式下调用connect函数 2.调用connect,正常情况下,因为TCP三次握手需要一些时间;而非阻塞调用只要不能立即完成就会返回错误,...
  • Windows (wince、 windows mobile、windows phone)错误代码大全 分类: WinCE WinCE 编译错误收集及分析 2011-04-11 15:26 546人阅读 评论(0) 收藏 举报 DWORD ErrorNum = GetLastError(); 〖0〗...
  • 请注意,在这种情况下WINDOWS套接口实现将在一段不确 定的时间内保留套接口以及其他资源,这对于想用所以套接口的应用程序来说有一定影响。 SO_OOBINLINE 带外数据放入正常数据流,在普通数据流中接收带外数据 int SO...
  • windows系统错误代码大全

    千次阅读 2008-12-18 15:56:00
    windows系统错误代码大全0000 操作已成功完成。0001 错误的函数。0002 系统找不到指定的文件。0003 系统找不到指定的路径。0004 系统无法打开文件。0005 拒绝访问。0006 句柄无效。0007 存储区控制块已损坏。0008 ...
  • WindowsXP注册表详解

    千次阅读 2015-10-11 16:58:21
     注册表是Windows操作系统的核心。它实质上是一个庞大的数据库,存放有计算机硬件和全部配置信息、系统和应用软件的初始化信息、应用软件和文档文件的关联关系、硬件设备说明以及各种网络状态信息和数据。可以说...
  • 打开VS2013,“文件”-“新建“-”项目“,在左边选择VisualC++下的WindowsDriver,选择WDF,然后选择KernelModeDriver(KMDF)VisualC++,输入你要创建的驱动的名称,点击“确定”就创建了一个KM...
  • 目录 延迟自动启动服务 ...Windows®服务开发的状态自从在 Windows NT® 中出现服务以来一直没有较大的改变,但是 Windows Vista® 和 Windows Server® 2008 打破了这一僵局。这其中的许多功能主
  • Windows 终端命令大全

    万次阅读 多人点赞 2018-09-12 20:18:44
    虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全、稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Windows 系统下运行DOS,....
  • 使用线程或异步调用来避免 DCOM 超时设定太长总是有人问我当 DCOM 无法完成远程实例化请求或...在 Windows NT 4.0 上,激活请求不会立即失败,DCOM 可能会花上一分钟或更长时间来返回失败的 HRESULT。DCOM 还可能花费
  • windows运行命令大全

    万次阅读 多人点赞 2018-04-20 16:38:59
    虽然随着计算机产业的发展,Windows 操作系统的应用越来越广泛,DOS 面临着被淘汰的命运,但是因为它运行安全、稳定,有的用户还在使用,所以一般Windows 的各种版本都与其兼容,用户可以在Windows 系统下运行DOS,...
  • (3)如果网络未通,则返回显示为请求超时(request timed out) 此时需要分析网络故障出现的原因,一般可以检查如下几点。 1)网络中是否有这台计算机,或者被测试计算机是否正在运行 2)被侧是计算机是否...
  • windows IPSec配置

    万次阅读 2018-11-17 11:11:28
    windows中就有些麻烦,需要在本地安全设置那里进行设置。 1)先看端口开启情况 进入cmd,输入命令netstat -na,查看端口开放情况 可以看到,开放了445这个危险端口。 2)进入本地安全设置新建规则 在管理...
  • windows2k启动

    千次阅读 2005-06-22 16:56:00
     当Windows 2000 setup运行时,它向硬盘上写入MBR(主引导记录),同时在这个磁盘驱动器的第一个可引导 分区(就是我们在fdisk后激活的分区)写入引导扇区,引导扇区的内容根据不同的文件系统格式而
  • 回顾 DB2 9.1 中的锁定超时分析使用 db2pd 工具和 db2cos 脚本进行锁定超时分析的方法包含以下几步: 使用一个特殊的 DB2 脚本 — 名为 db2cos — 在每次调用 db2cos 脚本时执行一个 db2pd 调用。db2pd 调用收集与...
  • Windows CE设备驱动开发之电源管理

    千次阅读 2012-06-02 16:28:33
    在定时器超时后,根据当前系统供电状况(使用外接电源或电池)进行不同的系统电源状态切换。 Platform Builder 提供的 Windows CE 运行时 image 示例均使用外接电源供电模式。你可以选择实现一套在使用电池供电时...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,814
精华内容 7,125
关键字:

windows激活超时