【发布时间】:2011-09-08 10:37:43
【问题描述】:
在使用socket() 时,我对 Linux 上协议定义之间的差异感到有些困惑。我正在尝试使用socket(PF_INET, SOCK_STREAM, proto) 监听 TCP 上的连接,其中proto (在我看来)是有争议的,或者至少看起来很奇怪。
来自<netinet/in.h>:
...
IPPROTO_IP = 0, /* Dummy protocol for TCP. */
...
IPPROTO_TCP = 6, /* Transmission Control Protocol. */
...
同意/etc/protocols:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
...
tcp 6 TCP # transmission control protocol
...
我从在线教程中了解到,也从手册页 tcp(7) 中了解到您使用初始化 TCP 套接字
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
它工作得很好,当然是一个TCP套接字。使用上述参数初始化套接字的一件事是代码
struct timeval timeout = {1, 0};
setsockopt(tcp_socket, 0, SO_RCVTIMEO, &timeout, sizeof(timeout); // 1s timeout
// Exactly the same for SO_SNDTIMEO here
工作得很好,但是不是在用IPPROTO_TCP替换所有协议参数(包括在socket()中)之后,而不是他们拥有的IPPROTO_IP,如上所述。
所以在尝试了不同之处之后,我需要问一些搜索问题:
- 为什么,当我将所有协议参数替换为
IPPROTO_TCP时,在设置超时时会出现错误 92(“协议不可用”),而协议 0 显然只是一个“虚拟”TCP? - 为什么
socket()需要知道它应该是流、数据报还是原始套接字的信息,而该信息(总是?)从协议中隐式知道,反之亦然? (即 TCP 是流协议,UDP 是数据报协议,...) - “虚拟 TCP”是什么意思?
- 什么是
hopopt,为什么它的协议号和“ip”一样?
非常感谢。
【问题讨论】: