Sockets: Network IPC Internet Socket UNIX Domain Socket
Dec 22, 2015
Sockets: Network IPC
Internet Socket UNIX Domain Socket
Sockets Allows processes to communicate
Process on the same machine Process on different machines connect via a
network Sockets are identified by socket
descriptors Implemented with file descriptors in UNIX Not all functions that work with file
descriptors work with sockets. See page 548 for which ones do work
Sockets
int socket(int domain, int type, int protocol);
domain defines the address family AF_INET – IPv4 AF_INET6 – IPv6 AF_UNIX – UNIX domain (covered
later) AF_UNSPEC – unspecified
Sockets type defines the type of socket
SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_STREAM
protocol defines which of the available protocols to use for this socket We usually use 0 for the default protocol AF_INET + SOCK_STREAM TCP AF_INET + SOCK_DGRAM UDP
Byte Ordering
In order to connect to a remote computer and use a socket, we need to use its address
LINUX is little-endian but TCP/IP uses big-endian byte ordering
Byte Ordering 4 conversion functions for TCP/IPuint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t hostshort);uint32_t ntohl(uint32_t netlong);uint16_t ntohs(uint16_t netshort);
h – host n - network
Binding a Socket
Binds a network address to a socket Used by server so a remote
computer can connect to the socketint bind(int sockfd, const struct sockaddr
*my_addr, socklen_t addrlen); sockfd socket descriptor addrlen size in bytes of struct pointed
to by my_addr
Binding a Socket my_addr points to a struct that
represents an address on the network Format of struct depends on specified
domain. So that we can use a single bind function, it is typecast to the generic
struct sockaddr { sa_family_t sa_family; char sa_data[]; …};
Binding a Socket IPv4 addresses are represented bystruct sockaddr_in { sa_family_t sin_family; /*addr family*/ in_port_t sin_port; /* port number */ struct in_addr sin_addr; /*IPv4 addr*/ unsigned char sin_zero[8]; /*LINUX only*/};struct in_addr { in_addr_t s_addr; /*IPv4 address*/};
listen
int listen(int sockfd, int backlog); Causes the server to wait for an
incoming connection sockfd socket descriptor of an open
socket backlog suggested max connection
requests to queue
acceptint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
Creates a new socket from those queued by listen function
Returns new socket descriptor on success or -1 on failure
Newly created socket used for send and recv
Old socket that we called listen on still exists waiting for more incoming connections
accept If we don’t care about the identity of the
client, we can pass in NULL for addr and addrlen
Otherwise, addr should point to a buffer and addrlen should be the size of the buffer in bytes
accept function blocks if no pending connect requests unless the socket is created non-blocking
connect
Used by client to connect to a serverint connect(int sockfd, const struct sockaddr *serv_addr,
socklen_t addrlen);
sockfd – socket descriptor of an open socket
sockaddr – address of server we wish to connect to
addrlen – size in bytes of the struct pointed to by sockaddr
Summery of Connecting Server
socket bind listen accept
Client socket connect
send and recvssize_t send(int s, const void *buf, size_t len, int flags);ssize_t recv(int s, void *buf, size_t len, int flags);
s is the socket descriptor for an open and connected socket
buf is a buffer of information to send or an empty buffer to receive information
len is the size of the buffer in bytes flags – zero or an OR of MSG_EOR (end of
record), MSG_OOB (out-of-band data) See page 565 for full list
sendto and recvfrom
sendto and recvfrom used with connectionless sockets (SOCK_DGRAM)
Server socket, bind, recvfrom
Client socket, sendto
shutdown and close close(sfd); will not deallocate the socket
until we close the last descriptor that references it (we may have several)
int shutdown(int s, int how); Use shutdown to force a full or partial
closure of a socket s is a socket descriptor how can be SHUT_RD, SHUT_WR or
SHUT_RDWR
Network Address Functions
inet_addr - converts an IP address in numbers-and-dots notation into an unsigned long (in_addr_t). Note: this function is deprecated!
inet_aton - converts an IP address in numbers-and-dots notation into an in_addr struct
int inet_aton(const char *cp, struct in_addr *inp);
Network Address Functions
inet_ntoa - converts an IP address in an in_addr struct into dots-and-numbers notation
char *inet_ntoa(struct in_addr in); inet_ntop - converts a network
address into a dots-and-numbers address
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
Network Address Functions
inet_pton - converts a network address in numbers-and-dots notion into a network address structure
int inet_pton(int af, const char *src, void *dst);
Network Addresses From Host Names
To get an address from a host name we need to obtain it from DNS
struct hostent *gethostbyname(const char *name);struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */};#define h_addr h_addr_list[0] /* for backward
compatibility */ This function marked obsolete by POSIX.1 See page 555 for getaddrinfo function
Peer Name
int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
Sets sockaddr with the name of the connect peer. Can be used by hosts after calling accept to get the name of a client
Hostname
int gethostname(char *name, size_t len);
Retrieves the hostname of the system running the process
UNIX Domain Sockets
Socket for communicating with another process on the same machine only
Provides an optimization since there is no network overhead
UNIX Domain Sockets
Uses sockaddr_un structure instead of sockaddr_in
struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX
*/ char sun_path[108]; /* pathname */};
UNIX Domain Sockets
When the socket is bound a new special file (type “s”) corresponding to sun_path is created
This file is NOT automatically deleted, so we should be careful to unlink it
If bind finds the file already exists, it will fail