Week 10 #
Sockets #
Another way for two processes to communicate
Characteristics of Sockets #
- Has 2 sides: Server and Client
- Server: has a publishable address
- Client: contacts Server by published address
- Unrelated processes, even on different computers, can contact each other through sockets
Socket Varieties #
By Domain #
- Unix Domain: Local to the computer, address is a filename
- IPv4: Over the network, 32-bit address + 16-bit port number
- IPv6: 128-bit address and over the network
By Abstraction Level #
- Datagram:
- Per packet
- Packet boundary preserved, packet order is not
- Unnoticed packet loss
- Stream:
- Network stack works hard to confirm, timeout, resend
- Preserves data order
- No packet boundary
Stream Socket Workflow #
Client #
- Call
socket
, creates the socket fd - Fill in the address struct and use
connect
to connect to the server at the address - Use the socket fd to communicate with the server
- Close the fd when done
Server #
- Call
socket
to create the server socket fd - Fill in the address struct and use
bind
to bind the sfd to the address - Call
listen
- Loop
- Call
accept(sfd)
to wait for client to connect, gets back a client fd - Use the cfd to communicate with client, close when done
- Call
- Close the server socket fd if no longer waiting for clients
Creating Sockets #
int socket(int family, int type, int protocol); // returns socket fd > 0, -1 if error
family
:AF_UNIX
,AF_INET
(IPv4),AF_INET6
(IPv6)type
:SOCK_DGRAM
,SOCK_STREAM
protocol
:0
IPv4 Addresses and Port struct #
- Adresses are 32-bit, and identifies network interfaces (computers)
- Each byte is seperated by dots. (ex
142.1.96.164
) dig
can look up IP Addresses from domain names by asking Domain Name Servers (DNS)- Port struct:
struct sockaddr_in { sa_family_t sin_family; // AF_INET in_port_t sin_port; // port, need to be in network byte order struct in_addr sin_addr; // IPv4 address, also in NBO }; struct in_addr { uint32_t s_addr; }
- Special addresses
127.0.0.1
: Loopback (You can see this example when usinglocalhost
or any web server running on your computer)0.0.0.0
: Request binding to all network interfaces
Endians and Network Byte Order #
- Big Endian (Network Byte Order): Left to right (ex. 772 in decimal = 03 04)
- Little Endian: Bytes are swapped (ex. 772 in decimal = 04 03)
- Use the library functions
htonl
(32-bit) andhtons
(16-bit) to convert from Little to Big Endian
bind
, accept
and connect
#
int bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
sockaddr
:sockaddr_in
(IPv4),sockaddr_in6
(IPv6),sockaddr_un
(UNIX)
int accept(int fd, struct sockaddr *client_addr, socklen_t addrlen);
- Returns new socket cfd for talking to client
client_addr
will recieve the address of client
int connect(int fd, const struct sockaddr *server_addr, socklen_t addrlen);
- Returns 0 if success, -1 on error
fd
can now talk to the server
Broken Pipes #
- If one end of the pipe is closed before the other one, the processes gets
SIGPIPE
- The default action is the processes gets killed
- Eg.
$ uniq longFile.txt | head -1 # 'head' end of pipe closes after the first line # but 'uniq' is still running, hence the process just ends
- To override the default, set action to
SIG_IGN
(ignore)