TCP Socket Call Sequence: Server
-
Create a socket (file descriptor)
int socket(int domain, int type, int protocol);-
domain: protocol family-
AF_UNIX: Unix sockets -
AF_INET: IPv4 sockets -
AF_INET6: IPv6 sockets
-
-
type: communication semantics-
SOCK_DGRAM: UDP -
SOCK_STREAM: TCP -
SOCK_RAW: raw network protocol access
-
-
TCP Socket Call Sequence: Server
-
Bind the socket to an address
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);-
sockfd: socket file descriptor -
addr,addrlen: server address and port
-
-
Mark the socket as a passive socket
int listen(int sockfd, int backlog);-
sockfdcan be now be used withaccept -
OS will queue up to
backlogpending connections
-
TCP Server: Rust
Code:
let socket = SocketAddr::from(([127, 0, 0, 1], 8888));
let listener = TcpListener::bind(socket)?;
-
Create a
SocketAddr(IP address + port number) - Bind a new socket to the address
TCP Server: Rust
Code:
let socket = SocketAddr::from(([127, 0, 0, 1], 8888));
let listener = TcpListener::bind(socket)?;
System Calls:
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 3setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0bind(3, {sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("127.0.0.1")}, 16) = 0listen(3, 128) = 0
FD 3 is a IP socket with the TCP protocol, queuing up to 128 connections
TCP Socket Call Sequence
Server:
-
Accept a connection on the socket
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);- Blocks until a connection is pending
-
sockfdcan then be reused to accept more clients
Client:
-
Create a socket
-
Connect to the server
int connect(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
TCP Server and Client: Rust
Server:
let (stream, socket) = listener.accept()?;
accept4(3, {sa_family=AF_INET, sin_port=htons(42694), sin_addr=inet_addr("127.0.0.1")}, [128 => 16], SOCK_CLOEXEC) = 4
Client:
let socket = SocketAddr::from(([127, 0, 0, 1], 8888));
let stream = TcpStream::connect(socket)?;
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_IP) = 3connect(3, {sa_family=AF_INET, sin_port=htons(8888), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
TCP Server and Client: Rust
impl Read for TcpStream {}
impl Write for TcpStream {}
Server:
stream.write_all("hello!".as_bytes())?;
recvfrom(4, "hello!", 4096, 0, NULL, NULL) = 6
Client:
let mut temp = [0; 4096];
let n = stream.read(&mut temp)?;
sendto(3, "hello!", 6, MSG_NOSIGNAL, NULL, 0) = 6