EE122: Socket Programming: Igor Ganichev Originally Prepared by DK Moon
EE122: Socket Programming: Igor Ganichev Originally Prepared by DK Moon
Socket API?
Q. What would you expect when learning a new Unix command (e.g., ls) ?
a) Source code b) Program options => Implementation detail => Interface
Socket API
Network programming interface
Socket API
Socket API
Network programming interface Application
Transport Network
TCP IP
UDP
Socket API
Sockets
Various sockets Any similarity?
Endpoint of a connection
Identified by IP address and Port number
Outline
Socket API motivation, background Types of sockets (TCP vs. UDP) Elementary API functions I/O multiplexing Project Distributed Cracking Appendix (not covered in the lecture)
Types of Sockets
Stream socket (aka TCP)
Connection-oriented
Requires connection establishment & termination
Reliable delivery
In-order delivery Retransmission No duplicates
Best-effort delivery
Arbitrary order of packet delivery No retransmission Possible duplicates
l l e w e poH! i H
UDP treats them as separate messages
Hope youre well Hi!
8
Bytes stream
l l e w o H 16 ! i H 3
9
Outline
Socket API motivation, background Types of sockets (TCP vs. UDP) Elementary API functions I/O multiplexing Project Distributed Cracking
IP version 4 address
Usually represented as dotted numbers for human readability
E.g., 128.32.132.214
Port number
Identifies a service (or application) on a host
E.g., TCP Port 80 => web service, UDP Port 53 => name service (DNS)
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
12
socket()
Many Unix system calls and library functions set errno on errors Macros for error codes (E + error name)
EINTR, EWOULDBLOCK, EINVAL, man func_name shows possible error code for the function name
struct sockaddr_in: Ipv4 socket address structure. (c.f., struct sockaddr_in6) INADDR_ANY: If server has multiple IP addresses, binds any address.
Endianess
Q) You have a 16-bit number: 0x0A0B. How is it stored in memory?
Increasing address
0x0A
0x0B
Increasing address
0x0B
0x0A
Big Endian
Little Endian
Endianness (contd)
Network byte order: Big endian
To avoid the endian problem
We must use network byte order when sending 16bit, 32bit , 64bit numbers. Utility functions for easy conversion
uint16_t htons(uint16_t host16bitvalue); uint32_t htonl(uint32_t host32bitvalue); uint16_t ntohs(uint16_t net16bitvalue); uint32_t ntohl(uint32_t net32bitvalue);
Hint: h, n, s, and l stand for host byte order, network byte order, short(16bit), and long(32bit), respectively
struct sockaddr_in: Ipv4 socket address structure. (c.f., struct sockaddr_in6) INADDR_ANY: If server has multiple IP addresses, binds any address.
Initialization Summary
Client
socket()
Server
socket() setsockopt(sock, SOL_SOCKET, SO_REUSEADDR) bind() listen()
Pitfalls
The order of the functions matter Do not forget to use htons() to handle port number
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
22
socket()
accept(): returns a new socket descriptor for a client connection in the connection-waiting queue.
This socket descriptor is to communicate with the client The passive socket (listening_sock) is not to communicate with a client
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
25
socket()
data_addr: address of data to send data_len: size of the data With blocking sockets (default), send() blocks until it sends all the data. With non-blocking sockets, sent_bytes may not equal to data_len
If kernel does not have enough space, it accepts only partial data You must retry for the unsent data
recv(): reads bytes from the socket and returns the number of read bytes.
Also OK with read() and readv()
close(): closes the socket descriptor We cannot open files/sockets more than 1024*
We must release the resource after use
* Super user can overcome this constraint, but regular user cannot.
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
29
socket()
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
30
socket()
Initialization: UDP
int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror(socket failed); abort(); }
Server
bind() listen()
Termination Data transfer Connection Initialization Establishment
32
socket()
Server
bind() listen()
Initialization Termination Data transfer
33
socket()
Server
bind()
Initialization Termination Data transfer
34
socket()
Server
bind()
Initialization Termination Data transfer
35
socket()
Client
socket()
Server
bind()
Initialization Termination Data transfer
36
socket()
sent_bytes = sendto(sock, data, data_len, 0, (struct sockaddr *) &sin, sizeof(sin)); if (sent_bytes < 0) { perror(sendto failed); abort(); }
As opposed to TCP, UDP packetizes data. So, sendto() sends all data or nothing.
recvfrom(): reads bytes from the socket and sets the source information Reading 0 bytes does not mean connection closed unlike TCP.
Recall UDP does not have a notion of connection.
UDP
Initialization
socket(AF_INET, SOCK_DGRAM, 0) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, ) bind()
Conneciton
connect() accept()
Data transfer
send() recv()
Termination
close()
Termination
close()
Outline
Socket API motivation, background Types of sockets (TCP vs. UDP) Elementary API functions I/O multiplexing Project Distributed Cracking
If no data available, recv() blocks. If blocked on one source, cannot handle other sources
Suppose what if a web server cannot handle multiple connections
Solutions
Polling using non-blocking socket Inefficient I/O multiplexing using select() simple Multithreading more complex. Not covered today
int opt = fcntl(sock, F_GETFL); Gets the sockets if (opt < 0) { option perror(fcntl failed); abort(); } Updates the sockets if (fcntl(sock, F_SETFL, opt | O_NONBLOCK) < 0) { perror(fcntl failed); option with non abort(); blocking option } while (1) { int read_bytes = recv(sock, buffer, sizeof(buffer), 0); if (read_bytes < 0) { if (errno == EWOULDBLOCK) { When no data, // OK. Simply no data we see EWOULDBLOCK } else { error code. perror(recv failed); abort(); } }
if (select(MAX(sock1, sock2) + 1, &read_set, NULL, NULL, &time_out) < 0) { perror(select failed); abort(); Pass NULL instead of } if (FD_ISSET(sock1, &read_set)) { // sock1 has data } if (FD_ISSET(sock2, &read_set)) { // sock2 has data }
Outline
Socket API motivation, background Types of sockets (TCP vs. UDP) Elementary API functions I/O multiplexing Project Distributed Cracking
Project 1
Project 1
Part 2
Hello crackers! I found that 19191 is not prime
Part 1
Project 2
Cracker App using our prime number service
Tip #1
How to check the host byte order of my machine?
union { uint16_t number; uint8_t bytes[2]; } test; test.number = 0x0A0B; printf(%02x%02x\n, test.bytes[0], test.bytes[1]);
Tip #2
How to get IP address from host name
Use gethostbyname()
struct sockaddr_in sin; struct hostent *host; host = gethostbyname(www.berkeley.edu); sin.sin_addr.s_addr = *(unsigned *) host->h_addr_list[0];
Tip #3
By default, Unix terminates the process with SIGPIPE if you write to a TCP socket which has been closed by the other side. You can disable it by:
signal(SIGPIPE, SIG_IGN);
OR