Controlling which congestion control algorithm is used in Linux

本文介绍了Linux内核中先进的网络堆栈及拥塞控制机制。拥塞控制算法包括BIC、NewReno、CUBIC等,并可通过/sys/net/ipv4/tcp_congestion_control文件配置默认算法。

Linux kernel has a quite advanced networking stack, and that's also true for congestion control. It is a very advanced implementation who's primary characteristics are modular structure and flexibility. All the specific congestion control algorithms are separated into loadable modules. The following congestion control mechanisms are available in the mainline kernel tree:

Default, system wide, congestion control algorithm is Cubic. You can check that by inspecting the content of the file /proc/sys/net/ipv4/tcp_congestion_control:
$ cat /proc/sys/net/ipv4/tcp_congestion_control  
cubic
So, to change system-wide default you only have to write a name of congestion control algorithm to the same file. For example, to change it to reno you would do it this way: 
# echo reno > /proc/sys/net/ipv4/tcp_congestion_control
# cat /proc/sys/net/ipv4/tcp_congestion_control
reno
Note that, to change the value, you have to be the root user. As the root you can specify any available congestion algorithm you wish. In the case the algorithm you specified isn't loaded into the kernel, via standard kernel module mechanism, it will be automatically loaded. To see what congestion control algorithms are currently loaded take a look into the content of the file /proc/sys/net/ipv4/tcp_available_congestion_control
$ cat /proc/sys/net/ipv4/tcp_available_congestion_control
vegas lp reno cubic
It is also possible to change congestion control algorithm on a per-socket basis using setsockopt(2) system call. Here is the essential part of the code to do that:
...
int s, ns, optlen;
char optval[TCP_CA_NAME_MAX];
...
s = socket(AF_INET, SOCK_STREAM, 0);
...
ns = accept(s, ...);
...
strcpy(optval, "reno");
optlen = strlen(optval);
if (setsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, optlen) < 0) {
    perror("setsockopt");
    return 1;
}
In this fragment we are setting congestion control algorithm to reno. Note that that the constantTCP_CA_NAME_MAX (value 16) isn't defined in system include files so they have to be explicitly defined in your sources.

When you are using this way of defining congestion control algorithm, you should be aware of few things:
  1. You can change congestion control algorithm as an ordinary user.
  2. If you are not root user, then you are only allowed to use congestion control algorithms specified in the file /proc/sys/net/ipv4/tcp_allowed_congestion_control. For all the other you'll receive error message.
  3. No congestion control algorithm is bound to socket until it is in the connected state.
You can also obtain current control congestion algorithm using the following snippet of the code:
optlen = TCP_CA_NAME_MAX;
if (getsockopt(ns, IPPROTO_TCP, TCP_CONGESTION, optval, &optlen) < 0) {
    perror("getsockopt");
    return 1;
}
Here you can download a code you can compile and run. To compile it just run gcc on it without any special options. This code will start server (it will listen on port 10000). Connect to it using telnet (telnet localhost 10000) in another terminal and the moment you do that you'll see that the example code printed default congestion control algorithm and then it changed it to reno. It will then close connection.

Instead of the conclusion I'll warn you that this congestion control algorithm manipulation isn't portable to other systems and if you use this in your code you are bound to Linux kernel.

<think>好的,我现在要解答用户关于“void-type in controlling expression”的问题。首先,我得理解用户的问题到底在问什么。控制表达式通常指的是条件语句(如if、while等)中的表达式部分。而void类型在C、C++等编程语言中通常表示没有返回值。所以用户可能在问,当控制表达式的类型是void时会发生什么,或者为什么会发生这种情况。 接下来,我需要回忆相关的编程知识。在C/C++中,void类型的表达式通常出现在函数没有返回值的时候。例如,如果有一个函数声明为void func(),那么调用这个函数的结果就是void类型。如果用户试图将这个函数调用作为控制表达式,比如if(func()) {...},这时候就会出现错误,因为控制表达式需要一个可以转换为布尔值的类型,而void无法转换。 此外,可能需要考虑其他情况,比如误用了逗号运算符或者其他操作导致表达式类型为void。例如,在C++中,如果写if (x=5, voidFunc()),这里逗号运算符的结果是最后一个表达式的类型,也就是void,同样会导致错误。 然后,我需要考虑用户可能的错误场景。例如,用户可能错误地在条件中调用了无返回值的函数,或者误用了某些操作符导致表达式类型变为void。这时候编译器会报错,提示无法将void类型用于条件表达式。 接下来,我需要组织回答的结构。首先解释void类型在控制表达式中的问题,然后举例说明常见的错误情况,接着解释编译器的行为,最后给出解决方法。这样用户能够逐步理解问题所在,并知道如何修正。 同时,要确保回答符合用户的要求:使用中文,结构清晰,分步解释,使用正确的LaTeX格式。例如,代码示例需要用行内公式的格式,或者独立段落,但这里可能更合适用代码块,不过用户要求用LaTeX,可能需要调整。不过根据系统指令,用户可见层可能不需要严格的LaTeX代码块,而是自然的中文解释加上适当的技术术语。 还需要注意,用户可能不太清楚术语,所以需要适当解释void类型和控制表达式的定义,但不要过于冗长。重点放在错误原因和解决方法上。 最后,检查是否有遗漏的情况,比如C和C++中的差异,或者其他语言是否也存在类似问题。但根据问题中的“void-type”,可能主要针对C/C++,所以可以集中在这些语言上。</think>在编程中,**void类型用于控制表达式**(如`if`、`while`、`for`的条件部分)时,会引发编译错误。以下是逐步解释: --- ### 1. **void类型的本质** - **void**表示“无类型”或“无返回值”,常见于函数声明: ```c void func() { ... } // 函数无返回值 ``` - 任何**void类型的表达式**(如调用无返回值的函数)本身不产生值。 --- ### 2. **控制表达式的要求** 控制语句(`if`/`while`/`for`等)的条件表达式需满足: - 必须能隐式转换为**布尔值**(`true`/`false`)。 - 例如: ```c if (x > 0) { ... } // 合法:x>0返回布尔值 ``` --- ### 3. **void类型导致的错误** 若控制表达式为`void`类型,编译器会报错: ```c if (func()) { ... } // 错误:func()返回void,无法作为条件 ``` - **原因**:`void`无法转换为布尔值,条件判断失去逻辑依据。 --- ### 4. **常见场景** #### 场景1:误用无返回值函数 ```c void check() { ... } if (check()) { ... } // 错误:check()返回void ``` **修复**:修改函数使其返回布尔值: ```c bool check() { return ...; } ``` #### 场景2:错误使用逗号运算符 ```c if (printf("Hello"), void_func()) { ... } // 错误:逗号表达式最终类型为void ``` **修复**:确保最后一个表达式有返回值: ```c if (printf("Hello"), 1) { ... } // 合法:1为整型,可转换为布尔值 ``` --- ### 5. **编译器行为** - **C/C++编译器**会直接报错,例如: ```plaintext error: void value not ignored as it ought to be ``` - **Java/C#等语言**:语法直接禁止void类型出现在条件中。 --- ### 6. **总结** - **根本问题**:`void`类型无法提供条件判断所需的逻辑值。 - **解决方法**: 1. 检查函数返回值类型。 2. 确保控制表达式最终为布尔值或可隐式转换的类型(如整型、指针)。 通过以上分析,可以避免因`void`类型导致的条件表达式错误。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值