• 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 ...

    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.


    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进行更改的权限。


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



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

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


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



    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)


    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打开电源选项。


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



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



    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.

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


    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函数,可以达到设置超时的...



    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 */     
    8.     sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
    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;  
    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.     }  
    22.     if(connect(sock,(struct sockaddr *)&address,sizeof(address))==false)  
    23.     {  
    24.         return false;  
    25.     }     
    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.     }  
    35.     fd_set Write, Err;  
    36.     FD_ZERO(&Write);  
    37.     FD_ZERO(&Err);  
    38.     FD_SET(sock, &Write);  
    39.     FD_SET(sock, &Err);  
    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.     }  
    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. 当使用默认...


    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:


    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:


    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.


    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/


  • TCP定时器之超时重传定时器

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


    1. 相关数据结构

    struct inet_connection_sock {
    	unsigned long		  icsk_timeout;
     	struct timer_list	  icsk_retransmit_timer;
    	__u8			  icsk_ca_state;
    	__u8			  icsk_retransmits;
    	__u8			  icsk_pending;

    2. 初始化


    static int tcp_v4_init_sock(struct sock *sk)
    void tcp_init_xmit_timers(struct sock *sk)
    	inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_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);
    	icsk->icsk_pending = icsk->icsk_ack.pending = 0;
    static inline void setup_timer(struct timer_list * timer,
    				void (*function)(unsigned long),
    				unsigned long data)
    	timer->function = function;
    	timer->data = data;

    3. 启动定时器


     *	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);
    	if (when > max_when) {
    		when = max_when;
    	if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0) {
    		icsk->icsk_pending = what;
    		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)
    	if (!mod_timer(timer, expires))

    3.1 启动时机


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

    4. 超时处理



    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;
    	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->icsk_pending = 0;
    	switch (event) {
    	case ICSK_TIME_PROBE0:

    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;
    	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.
    		if (tcp_time_stamp - tp->rcv_tstamp > TCP_RTO_MAX) {
    			goto out;
    		tcp_enter_loss(sk, 0);
    		tcp_retransmit_skb(sk, tcp_write_queue_head(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)
    			} else {
    				if (icsk->icsk_ca_state == TCP_CA_Recovery)
    		} else if (icsk->icsk_ca_state == TCP_CA_Loss) {
    		} else {
    	if (tcp_use_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;
    		inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
    					  min(icsk->icsk_rto, TCP_RESOURCE_PROBE_INTERVAL),
    		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_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)


    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);
    	int retry_until;
    	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
    		if (icsk->icsk_retransmits)
    		retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
    	} else {
    		if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
    			/* Black hole detection */
    			tcp_mtu_probing(icsk, sk);
    		retry_until = sysctl_tcp_retries2;
    		if (sock_flag(sk, SOCK_DEAD)) {
    			//如果该socket的RTO还没有超过最大RTO 120s,那么认为它还是存活的,
    			const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
    			retry_until = tcp_orphan_retries(sk, alive);
    			if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
    				return 1;
    	if (icsk->icsk_retransmits >= retry_until) {
    		/* Has it gone just too far? */
    		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)
    	int retries = sysctl_tcp_orphan_retries; /* May be zero. */
    	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. */
    	if (retries == 0 && alive)
    		retries = 8;
    	return retries;

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


    /* 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);
    	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. */
    	if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset)
    		orphans <<= 1;
    	if (sk->sk_err_soft)
    		orphans <<= 1;
    	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;
    		if (do_reset)
    			tcp_send_active_reset(sk, GFP_ATOMIC);
    		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()


    /* 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.
    	if (atomic_read(&sk->sk_wmem_alloc) >
    	    min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
    		return -EAGAIN;
    	if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
    		if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
    		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;
    	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. */
    	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);
    	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.
    	TCP_SKB_CB(skb)->when = tcp_time_stamp;
    	err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
    	if (err == 0) {
    		/* Update global TCP statistics. */
    		//如果之前[snd_una, snd_nxt)之间还没有数据包发生重传,那么
    		if (!tp->retrans_out)
    			tp->lost_retrans_low = tp->snd_nxt;
    		TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;
    		tp->retrans_out += tcp_skb_pcount(skb);
    		/* Save stamp of the first retransmit. */
    		if (!tp->retrans_stamp)
    			tp->retrans_stamp = TCP_SKB_CB(skb)->when;
    		/* snd_nxt is stored to detect loss of retransmitted segment,
    		 * see tcp_input.c tcp_sacktag_write_queue().
    		TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
    	return err;

    6. 系统参数


    对应系统目录/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.



    对应系统目录/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.



    对应系统目录/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.



    对应系统目录/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.



    对应系统目录/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
  • 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
  • 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
  • 打开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