From APUE
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Where:
type
can be SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET, SOCK_STREAM
, and protocol
can be IPPROTO_TCP
, IPPROTO_UDP
, ...Can SOCK_DGRAM
work with IPPROTO_UDP
, but not with IPPROTO_TCP
?
Can SOCK_STREAM
work with IPPROTO_TCP
, but not with IPPROTO_UDP
?
If answers are yes, does it mean that we don't need to specify protocol
when type
is SOCK_DGRAM
or SOCK_STREAM
?
From the man page for socket(2)
:
The protocol specifies a particular protocol to be used with the socket. Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. However, it is possible that many protocols may exist, in which case a particular protocol must be specified in this manner. The protocol number to use is specific to the “communication domain” in which communication is to take place; see protocols(5). See getprotoent(3) on how to map protocol name strings to protocol numbers.
So whether the protocol field needs to be specified or not depends both on the domain and type field. Assuming domain is AF_INET
, i.e. IPv4, then the protocol field should be set to 0 for both SOCK_DGRAM
and SOCK_STREAM
. The man page for ip(7)
shows this:
SYNOPSIS
#include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> /* superset of previous */ tcp_socket = socket(AF_INET, SOCK_STREAM, 0); udp_socket = socket(AF_INET, SOCK_DGRAM, 0); raw_socket = socket(AF_INET, SOCK_RAW, protocol);
...
An IP socket is created by calling the socket(2) function as socket(AF_INET, socket_type, protocol). Valid socket types are SOCK_STREAM to open a tcp(7) socket, SOCK_DGRAM to open a udp(7) socket, or SOCK_RAW to open a raw(7) socket to access the IP protocol directly. protocol is the IP protocol in the IP header to be received or sent. The only valid values for protocol are 0 and IPPROTO_TCP for TCP sockets, and 0 and IPPROTO_UDP for UDP sockets. For SOCK_RAW you may specify a valid IANA IP protocol defined in RFC 1700 assigned numbers.
The ipv6(7)
man page shows something different:
SYNOPSIS
#include <sys/socket.h> #include <netinet/in.h> tcp6_socket = socket(AF_INET6, SOCK_STREAM, 0); raw6_socket = socket(AF_INET6, SOCK_RAW, protocol); udp6_socket = socket(AF_INET6, SOCK_DGRAM, protocol);
It seems that for IPv6 you can specify the protocol
field, although the man page doesn't say anything regarding what values are allowed.
The answer by dbush is outdated. Here's what current man page for ip(7)
states:
protocol is the IP protocol in the IP header to be received or sent. Valid values for protocol include: • 0 and IPPROTO_TCP for tcp(7) stream sockets; • 0 and IPPROTO_UDP for udp(7) datagram sockets; • IPPROTO_SCTP for sctp(7) stream sockets; and • IPPROTO_UDPLITE for udplite(7) datagram sockets. For SOCK_RAW you may specify a valid IANA IP protocol defined in RFC 1700 assigned numbers.
As you can see, currently there are two different protocols for each of the stream and datagram socket types. And the protocol
parameter is what specifies which one of them to use for the corresponding socket type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With