Socket example 1 Berkeley Sockets Details for everyday use Carsten Griwodz
Socket example 1
Berkeley SocketsDetails for everyday use
Carsten Griwodz
Socket example 2
Data types
Basic data types Have a certain number of bits Not very important in platform-dependent
non-networked applications Not very important in platform-dependent
networked applications Very important in platform-independent
networked applications
Socket example 3
Data types
Basic data types C data types
char unsigned char - 8 bitsshort unsigned short - 16 bitsint unsigned int - 32 (or 64) bitslong unsigned long - 32 or 64 bitslong long unsigned long long - 64 (or 128) bits
Socket API portable typessize_t – 32 bits unsigned, 0 – 2^32-1ssize_t – 32 bits signed, -2^31 – 2^31-1
Socket example 4
IP addresses and hostnames
IPv4 host address When written on paper, it looks like 129.240.71.213
• ”dotted decimal notation” Represents a 32 bit address Binary in bits
• 10000001 11110000 01000111 11010101 Hexadecimal in bytes
• 0x81 0xf0 0x47 0xd5 One 4 byte int on x86, StrongARM, XScale, …
• 0xd547f081 One 4 byte int on PowerPC, POWER, Sparc, …
• 0x81f047d5 In network byte order
• 0x81f047d5
Socket example 5
IP addresses and hostnames
On x86 etc. ntohl(0x81f047d5) == 0xd547f081
On PowerPC etc. ntohl(0x81f047d5) == 0x81f047d5
Socket example 6
IP addresses and hostnames
IPv4 host address Corresponds to one network interface card
(NIC) IPv4 network address
Looks like 129.240.69.0/24• Refers to add addresses that that the same first
24 bits• 10000001 11110000 01000111 11010101• 129.240.69.213 is in that network
Socket example 7
IP addresses and hostnames
IPv4 networks Institutes and companies own network address ranges
• e.g. 129.240.0.0/16 - UiO• e.g. 9.0.0.0/8 – IBM
Institutes and companies assign addresses to their computers• Fixed addresses• Temporary addresses
0 network host
10 network host
110 network host
1110 multicast address
Class A addresses
Class B addresses
Class C addresses
Class D or multicast addresses
1.0.0.0/8 - 127.0.0.0/8
128.0.0.0/16 - 191.255.0.0/16
192.0.0.0/24 -223.255.255.0/24
224.0.0.0 -239.255.255.255
Socket example 8
IP addresses and hostnames
IPv4 networks Institutes and companies own network address ranges
• e.g. 129.240.0.0/16 - UiO• e.g. 9.0.0.0/8 – IBM
Institutes and companies assign addresses to their computers
• Fixed addresses• Temporary addresses
They can also create subnets• IFI has subnets of UiO’s address space• E.g. 129.250.69.0/24• 129.250.69.0 can’t be used for a computer, it’s the
network’s address• 129.250.69.255 can’t be used for a computer, it’s an
address for all computers in the network, the broadcast address
Socket example 9
IP addresses and hostnames
These are many addresses Why do we need IPv6?
Most IPv4 addresses have owners• No matter whether the addresses are needed• Most in the US, using 1%• Several in Europe• Really tight in Asia, only assigned when need is proven
IPv6 addresses 128 bits In text
• 2FFF:80:0:0:0:0:94:1 – 8 times 16 bits• Hard to remember own address
001 13 bit top level 32 bit next level 16 bit site level 64 bit interface id
Socket example 10
IP addresses and hostnames
Hostnames More exactly fully qualified host names Look like niu.ifi.uio.no
• Host niu• In subdomain ifi, Institutt for Informatik• In domain uio, Universitet i Oslo• In top level domain no, Norway
Who decided this? .no - IANA gave it to Uninett .uio - Uninett gave it to UiO .ifi - USIT, UiO’s drift, gave it to IFI niu - IFI drift gave it to the machine
Socket example 11
Name resolution
Gethostbyname Takes a hostname Returns information
about that hostname Including its IP
address
How?
struct hostent *hostp; struct sockaddr_in serveraddr; int sock;
/* Look in DNS for the IP address of the name */ if ((hostp = gethostbyname(machine)) == 0) { fprintf(stderr,“Unknown machine %s\n",machine); exit(1); }
bzero((void *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; memcpy(&serveraddr.sin_addr, hostp->h_addr, hostp->h_length); serveraddr.sin_port = htons(port_number);
Socket example 12
Name resolution
Gethostbyname Takes a hostname Returns information
about that hostname Including its IP
address
How? First:
Look into /etc/hosts But only for few,
special, well-known hosts
## list of statically known hosts#127.0.0.1 localhost129.27.2.1 argul.ifi.uio.no argul129.27.2.21 fileserver.ifi.uio.no fileserver
Socket example 13
Name resolution
Gethostbyname Takes a hostname Returns information
about that hostname Including its IP
address
How? Then:
Using DNS the Domain Name
System
a121.ifi.uio.no
ifi.uio.no
Root name server
gaia.cs.umass.edu
dns.umass.edu
1
2 34
5
6
Socket example 14
Name resolution
Gethostbyname Takes a hostname Returns information
about that hostname Including its IP
address
Return value Pointer tostruct hostent
Contains more than just an IP address
• Other names• All addresses
#define h_addr h_addr_list[0]
struct hostent{ /* official hostname */ char* h_name; /* alias names of the host * entry NULL indicates end of the list */ char **h_aliases; /* host address type, e.g. AF_INET */ int h_addrtype; /* length of each address */ int h_length; /* list of addresses, primary is 0th entry * entry 0 indicates end of the list */ char** h_addr_list;};
Socket example 15
Name resolution
Finding the own hostname Command line
ifconfig –a (Unix) ipconfig /a (Windows) Gives you all IP addresses Typically 2:
• 127.0.0.1 localhost• and the actual one
Inside a program Difficult without a
connected socket With a connected socket:
• struct hostent* getsockname(int sock);
• Similar to gethostbyname
eth0 Link encap:Ethernet HWaddr 00:C0:4F:A3:0C:D3 inet addr:129.240.70.96 Bcast:129.240.71.255 Mask:255.255.248.0 UP BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1 RX packets:40543011 errors:65 dropped:0 overruns:203 frame:65 TX packets:9222810 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:3360933562 (3205.2 Mb) TX bytes:2321704496 (2214.1 Mb) Interrupt:19 Base address:0xfcc0
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:26429 errors:0 dropped:0 overruns:0 frame:0 TX packets:26429 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:5877172 (5.6 Mb) TX bytes:5877172 (5.6 Mb)
Socket example 16
Netmasks
Help your computer find the way All computers with addresses in the same network can be
reached directly• If you know your own computer’s address, e.g. 129.240.70.96• … and the relevant bits of your network, e.g. /24• … you know that all computers with addresses 129.240.70.?
are in the same network For each computer with another address, a member of the
own network (computer or router) must be found that can send the data into the right direction
• This is sometimes wrong• Understanding of network addresses becomes important
Tell your computer its network address For computers with a fixed IP address: set up once For computers with a dynamic address: set up together
with address
Socket example 17
Netmasks
The computer Is not told directly that it’s on the network 129.240.70.0/24 Instead it is told that it’s address is 129.240.70.97 And that its netmask is 255.255.255.0 – these are 24 bits It figures the network address out from this
In ifconfig or ipconfig Lists hostname
• E.g. 129.240.70.97 Lists netmask
• e.g. 255.255.255.0• Or 0xffffff00• Or the highest 24 bits set
Implies that• 129.240.70.97• is part of the subnet 129.240.70.97/24• which is the same as 129.240.70.0/24
This answer from ifconfig implies also that• All computers in the net 129.240.70.0/24 are reachable directly• Without router
Socket example 18
Binding TCP client sockets to ports Main reasons to do this
Use a specific network card
Other potential reasons Firewalls may restrict
open ports Server demands
connection from a priviledged port
• 0 – 1023 Associate virtual circuit
tags with source ports
int boundconnect( char* servername, int port, int ownport ){ … if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { … } bzero(&ownaddr, sizeof(ownaddr)); ownaddr.sin_family = AF_INET; ownaddr.sin_addr.s_addr = INADDR_ANY; ownaddr.sin_port = htons(ownport); if (bind(sock, (struct sockaddr *)&ownaddr, sizeof(ownaddr)) < 0) { … }
if ((hostp = gethostbyname(machine)) == 0) { … } bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; memcpy(&serveraddr.sin_addr, hostp->h_addr, hostp->h_length); serveraddr.sin_port = htons(port_number); if (connect(sock, (struct sockaddr *)&serveraddr, sizeof serveraddr) < 0) { … } return sock;}
Socket example 19
Connecting TCP socket
CLOSED
LISTEN
SYN_REVD
ESTABLISHED
CLOSE_WAIT
LAST_ACK
CLOSED
SYN_SENT
ESTABLISHED
FIN_WAIT_1
FIN_WAIT_2
TIME_WAIT
socketbind
listen
socket
connect
Send SYN
Rcvd SYN, ACKSend ACKread
write
Send FINRecv ACK
Recv FIN,Send ACK
Wait30 sec
close
Recv SYN,Send ACKand SYN
Recv ACKreadwriteRecv FIN,
Send ACK
Send FIN
Recv ACK
Client Server
Socket example 20
TCP Handshake
LISTEN
SYN_REVD
ESTABLISHED
CLOSED
SYN_SENT
ESTABLISHED
connect
Send SYN
Rcvd SYN, ACKSend ACK
Recv SYN,Send ACKand SYN
Recv ACK
Client Server
Socket example 21
Connecting UDP sockets
Datagram service UDP Usually unconnected connect can be used
Has only local meaning Local UDP ”remembers” a target socket
Advantage Reading and writing is simpler Possible to figure best packet size
Disadvantage Can use unconnected sockets to send to several
receivers Connected sockets only to one
Socket example 22
Reading and writing function calls int read( int sock, void* buffer, int n)
sock must be connected int recv( int sock, void* buffer, int n,
int options ) sock must be connected Sometimes useful option MSG_PEEK: read packet but leave
it in the queue int recvfrom( int sock, void* buffer, int n,
int options, struct sockaddr* src, int* srclen ) Meant for unconnected sockets If sock is connected, src is identical to sockaddr from
accept
Socket example 23
Reading and writing function calls int write( int sock, void* buffer, int n)
sock must be connected int send( int sock, void* buffer, int n,
int options ) sock must be connected
int sendto( int sock, void* buffer, int n, int options, struct sockaddr* dest, int destlen ) Meant for unconnected sockets If sock is connected, dest address must refer to the other
side
Socket example 24
Select
Complicated at first But very useful Can wait for activity on
many sockets New connections on
request sockets New data on connected
sockets Closing of a connected
socket Ready-to-send on a
socket Can wait for user input Can wait for timeouts
int select( int max_fd, fd_set* read_set, fd_set* write_set, fd_set* except_set, struct timeval* timeout );
Socket example 25
Select
For servers Serve many clients at
once Handle clients that
close connections, clients that crash, …
For the chat example Wait for data from
chat partner Wait for typing of the
user
int select( int max_fd, fd_set* read_set, fd_set* write_set, fd_set* except_set, struct timeval* timeout );
Socket example 26
Select
read_set Arriving connect
requests Arriving data Closing sockets
write_set Non often used Non-blocking send is
finished
except_set Hardly ever used sendto(.,.,.,MSG_OOB)
int select( int max_fd, fd_set* read_set, fd_set* write_set, fd_set* except_set, struct timeval* timeout );
Socket example 27
Select
Using only the read_set is typical
Clear the read_set Must be done every time
Put all sockets into the read set
Find the highest socket number, add 1
NULL timeout Means forever
Call select waits for arriving data
void wait_for_all(int clientsock[], int clients){ fd_set read_set; int i,act,top=0;
FD_ZERO(&read_set); for( i=0; i<clients; i++ ) { FD_SET(clientsock[i],&read_set); top = MAX(top,clientsock[i]); }
act = select( top+1, &read_set, NULL, NULL, NULL); …}
Socket example 28
Select
select can also wait only for a timeout Without sockets
Timeout parameter NULL means wait
forever Timeval {5,0} means
wait 5 seconds Timeval {0,0} means
don’t wait at all
void wait_some_time(int sec, int usec){ struct timeval timeout; timeout.tv_sec = sec; timeout.tv_usec = usec;
act = select( 0, NULL, NULL, NULL, &timeout ); …}
Socket example 29
Safe writing
You never know when something strange happens on your TCP connection
Safe writing is necessary Code from last lecture
Considers closing of the socket
int safewrite(int so, char buf[], int l){ int i; if (i=write(so, buf, l)==0) { printf("Can't write to socket, connection is closed" ); exit(1); } return i;}
Socket example 30
Safer writing
Not all data may be sent at once TCP takes as much as it wants to Try to send again
• If there was no error
Socket example 31
Safer writingint safewrite( int sock, char buffer[], int len ){ int ij=0; do { i = write( sock, &buffer[j], len ); if( i == -1 ) { perror( “Error writing to socket” ); exit( 1 ); } else if( i == 0 ) { printf( “The socket has been closed, quitting\n” ); exit( 1 ); } len = len – i; j = j + i; } while( len > 0 ); return 1;}
Socket example 32
Safer writing
Not all data may be sent at once TCP takes as much as it
wants to Try to send again
• If there was no error• If there was no
important error
Socket example 33
Safer writing else if( i == 0 ) { printf( “The socket has been closed, quitting\n” ); exit( 1 ); } else if( i > 0 ) { len = len – i; j = j + i; } } while( len > 0 ); return 1;}
int safewrite( int sock, char buffer[], int len ){ int I,j=0; do { i = write( sock, &buffer[j], len ); if( i == -1 ) { switch( errno ) { case EINTR : /* do nothing, no problem */ break; default: perror( “Error writing to socket” ); exit( 1 ); } }
Socket example 34
Safer writing
Not all data may be sent at once
TCP takes as much as it wants to
Try to send again• If there was no error• If there was no important
error You may receive a signal
These are alarm signals in case of emergencies
Pressing CTRL-C raises a signal
• SIGKILL An interrupt that ends your
program if you don’t handle it Server that use TCP
• Get SIGPIPE often• When the receiver crashes in
the middle of a write
Socket example 35
Safer writing default: perror( “Error writing to socket” ); exit( 1 ); } } else if( i == 0 ) { printf( “The socket has been closed, quitting\n” ); exit( 1 ); } else if( i > 0 ) { len = len – i; j = j + i; } } while( len > 0 ); return 1;}
int main( ){ … signal( SIGPIPE, SIG_IGN ); /* I don’t want to do much */ …}
int safewrite( int sock, char buffer[], int len ){ int I, j = 0; do { i = write( sock, &buffer[j], len ); if( i == -1 ) { switch( errno ) { case EINTR : /* do nothing, no problem */ break; case EPIPE : /* do nothing, will write 0 next round */ break;
Socket example 36
Safer writing
Not all data may be sent at once
TCP takes as much as it wants to
Try to send again• If there was no error• If there was no important
error You may receive a signal
These are alarm signals in case of emergencies
Pressing CTRL-C raises a signal
• SIGKILL An interrupt that ends your
program if you don’t handle it Server that use TCP
• Get SIGPIPE often• When the receiver crashes in
the middle of a write
Slow clients block the server Important if your server has
other things to do For example sending data
to many clients at once• Send only the data that
you can send immediately• Send more data when the
connection is ready to take more
Set the socket in non-blocking mode …
… and use select
Socket example 37
Safer writing default: perror( “Error writing to socket” ); return -1; } } else if( i == 0 ) { printf( “The socket has been closed, quitting\n” ); return -1; } else if( i > 0 ) { len = len – i; j = j + i; } return i;}
int main( ){ … signal( SIGPIPE, SIG_IGN ); /* I don’t want to do much */ …}
int safewrite( int sock, char buffer[], int len ){ int I, j = 0; i = write( sock, &buffer[j], len ); if( i == -1 ) { switch( errno ) { case EINTR : /* do nothing, no problem */ break; case EPIPE : /* do nothing, will write 0 next round */ break;
Socket example 38
Safer writing FD_ZERO( &writable ); for( i=0; i<nsock; i++ ) { FD_SET( sock[i], &writable ); max=MAX(sock[i],max); } retval = select( max+1, NULL, &writable, NULL, NULL ); if( retval > 0 ) { for( i=0; i<nsock; i++ ) { if( FD_ISSET( sock[i], &writable ) ) { retval = safewrite( sock[i], &buf[w[i]], l[i] ); … l[i] = l[i] – retval; /* if no error but not finished */ w[i] = w[i] + retval; if( l[i] > 0 ) again = 1; } } } } free( w );}
int createASocket( char machine[], int port_number ){ … sock[i] = TCPClientSocket(machine, port_number); int retval = fcntl( sock[i], F_SETFL, O_NONBLOCK); if( retval == -1 ) { perror( “Could not set socket into non-blocking mode” ); } …}
void safeWriteToMany( int sock[], int nsock, char buf [], int l[]){ int i, retval, again=1, max=0; int* w; fd_set writable; w = (int*)malloc( nsock ); memset( w, 0, sizeof(int)*nsock ); while( again == 1 ) { again = 0;
Socket example 39
Socket options
Two ways to set socket options setsockopt( int sock, int level,
int optname, void* optvalue, int optlen )
• Options for reading and writing all types of sockets
• Often used insetsockopt( request_sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
fcntl( int sock, int optname, long optvalue );
• Options for reading and writing all types of sockets, files, pipes, user input, graphical output
• Often used in fcntl( sock[i], F_SETFL, O_NONBLOCK);
Socket example 40
Summary
Names and addresses IP addresses Fully qualified hostnames Domain Name System
• How to use it
Connections in TCP and UDP Functions
The select function call Several functions for reading and writing
Writing really safe To one To many