我正在阅读并尝试了解C
,并且几年前我尝试用Java chat
和UDP
编制TCP
,并且就像我把它拉下来一样......我做不到。
我想编写套接字并且我正在阅读大量的文档,但总有一部分不清楚,每个踢文档都有一个缺陷。
例如,有一个关于
int socket(int domain, int type, int protocol);
我将使用的域名AF_INET
,如果我想要一个TCP
套接字,我认为类型应该是SOCK_STREAM
,但什么是协议?文档说它应该是0 ...为什么???它是什么?
答案 0 :(得分:3)
来自socket的手册页:
协议指定要与套接字一起使用的特定协议。通常,只有一个协议支持给定协议族中的特定套接字类型,在这种情况下协议可以指定为0.但是,可能存在许多协议,在这种情况下,必须在此指定特定协议方式。要使用的协议号特定于进行通信的“通信域”;见协议(5)。请参阅getprotoent(3),了解如何将协议名称字符串映射到协议号。
根据协议的手册页:
此文件是纯ASCII文件,描述了TCP / IP子系统提供的各种DARPA Internet协议。应该参考它而不是使用ARPA包含文件中的数字,或者更糟糕的是,只是猜测它们。这些数字将出现在任何IP标头的协议字段中。
每一行的格式如下:
协议编号别名......
...
/ etc / protocols协议定义文件。
在我的linux框上的/ etc / protocols文件中:
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # hop-by-hop options for ipv6
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group management protocol
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
cbt 7 CBT # CBT, Tony Ballardie <A.Ballardie@cs.ucl.ac.uk>
egp 8 EGP # exterior gateway protocol
igp 9 IGP # any private interior gateway (Cisco: for IGRP)
bbn-rcc 10 BBN-RCC-MON # BBN RCC Monitoring
...
根据getprotocol的手册页:
getprotobyname()函数返回数据库中与协议名称名称匹配的条目的protoent结构。如有必要,将打开与数据库的连接。
...
原始结构的定义如下:
struct protoent { char *p_name; /* official protocol name */ char **p_aliases; /* alias list */ int p_proto; /* protocol number */ }
所以,如果你通过&#34; ip&#34; getprotobyname()它将返回0,这是你正在使用的数字。但即使您不知道协议的名称,直接使用0也总是安全的。
答案 1 :(得分:1)
可能有不同的协议支持特定套接字类型,因此您也可以在protocol
中指定socket(2)
。
从联机帮助页(强调我的):
协议规定了与之一起使用的特定协议 插座。通常只有一个协议支持a 在这种情况下,给定协议族中的特定套接字类型 协议可以指定为0。 但是,可能存在许多协议,在这种情况下必须以这种方式指定特定协议。
因此将协议指定为0
不是强制。实际上0
意味着标准库会为您找出正确的协议。但您可以明确指定它,这样做完全有效。
在Linux上,您可以通过以下方式查看可用的协议:
$ cat /etc/protocols
# Internet (IP) protocols
#
# Updated from http://www.iana.org/assignments/protocol-numbers and other
# sources.
# New protocols will be added on request if they have been officially
# assigned by IANA and are not historical.
# If you need a huge list of used numbers please install the nmap package.
ip 0 IP # internet protocol, pseudo protocol number
hopopt 0 HOPOPT # IPv6 Hop-by-Hop Option [RFC1883]
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # Internet Group Management
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
答案 2 :(得分:1)
socket()的最后一个协议参数可以与原始数据包一起使用。我会尝试解释它。
如果使用原始套接字从TCP堆栈获取数据包,则可以使用此参数控制要发送/接收的数据包数据量。
socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
以上调用将为您提供一个原始数据包,其中内核将处理数据包到IP头。您必须在发送数据包时手动填写其余数据包,或者当您读取数据包时,内核将提供TCP标头的内容以及数据。
另一方面:
socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
使用 IPPROTO_RAW ,您可以从IP层向上控制数据包。即内核将为您提供以太网头的服务,其余的数据包在您的控制之下。