Transcript Data types
Berkeley Sockets
Details for everyday use
Carsten Griwodz
Socket example
1
Data types
Basic data types
Have a certain number of bits
Not very important in platform-dependent nonnetworked applications
Not very important in platform-dependent
networked applications
Very important in platform-independent networked
applications
Socket example
2
Data types
Basic data types
C data types
char
short
int
long
long long
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
-
8 bits
16 bits
32 (or 64) bits
32 or 64 bits
64 (or 128) bits
Socket API portable types
size_t – 32 bits unsigned, 0 – 2^32-1
ssize_t – 32 bits signed, -2^31 – 2^31-1
Socket example
3
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
4
IP addresses and hostnames
On x86 etc.
ntohl(0x81f047d5) == 0xd547f081
On PowerPC etc.
ntohl(0x81f047d5) == 0x81f047d5
Socket example
5
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
6
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
Class A addresses
0 network
Class B addresses
10 network
Class C addresses
110 network
Class D or multicast
addresses
1110 multicast address
host
1.0.0.0/8 - 127.0.0.0/8
host
128.0.0.0/16 - 191.255.0.0/16
host
192.0.0.0/24 223.255.255.0/24
224.0.0.0 239.255.255.255
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
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
8
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
9
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
10
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
11
Name resolution
Gethostbyname
Takes a hostname
Returns information
about that hostname
Including its IP address
#
# list of statically known hosts
#
127.0.0.1
localhost
129.27.2.1 argul.ifi.uio.no argul
129.27.2.21 fileserver.ifi.uio.no fileserver
How?
First:
Look into /etc/hosts
But only for few, special,
well-known hosts
Socket example
12
Name resolution
Root name server
Gethostbyname
Takes a hostname
Returns information
about that hostname
Including its IP address
2
5
3
4
How?
Then:
Using DNS
the Domain Name
System
ifi.uio.no
1
dns.umass.edu
6
a121.ifi.uio.no
gaia.cs.umass.edu
Socket example
13
Name resolution
Gethostbyname
Takes a hostname
Returns information
about that hostname
Including its IP address
Return value
Pointer to
struct hostent
Contains more than just
an IP address
#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;
};
• Other names
• All addresses
Socket example
14
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:
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)
• struct hostent*
getsockname(int
sock);
• Similar to gethostbyname
Socket example
15
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
16
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
17
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
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;
• 0 – 1023
Associate virtual circuit
tags with source ports
}
Socket example
18
Connecting TCP socket
Client
Server
socket
bind
socket
connect
CLOSED
Wait
30 sec
Send SYN
TIME_WAIT
SYN_SENT
Recv FIN,
Send ACK
read
write
FIN_WAIT_2
Rcvd SYN, ACK
Send ACK
ESTABLISHED
CLOSED
Recv ACK
LAST_ACK
Send FIN
FIN_WAIT_1
LISTEN
Recv SYN,
Send ACK
and SYN
Send FIN
CLOSE_WAIT
close
Recv ACK
listen
Recv FIN,
Send ACK
SYN_REVD
read
write
Recv ACK
ESTABLISHED
Socket example
19
TCP Handshake
Client
Server
CLOSED
connect
Send SYN
SYN_SENT
LISTEN
Recv SYN,
Send ACK
and SYN
Rcvd SYN, ACK
Send ACK
ESTABLISHED
SYN_REVD
Recv ACK
ESTABLISHED
Socket example
20
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
21
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
22
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
23
Select
Complicated at first
But very useful
int select( int max_fd,
fd_set* read_set,
fd_set* write_set,
fd_set* except_set,
struct timeval* timeout );
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
Socket example
24
Select
int select( int max_fd,
fd_set* read_set,
fd_set* write_set,
fd_set* except_set,
struct timeval* timeout );
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
Socket example
25
Select
int select( int max_fd,
fd_set* read_set,
fd_set* write_set,
fd_set* except_set,
struct timeval* timeout );
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)
Socket example
26
Select
void wait_for_all(int clientsock[], int clients)
{
fd_set read_set;
int i,act,top=0;
Using only the read_set is
typical
Clear the read_set
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);
…
}
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
Socket example
27
Select
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 );
…
}
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
Socket example
28
Safe writing
You never know when
something strange happens
on your TCP connection
Safe writing is necessary
Code from last lecture
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;
}
Considers closing of the
socket
Socket example
29
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
30
Safer writing
int 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
31
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
32
Safer writing
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 );
}
}
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;
}
Socket example
33
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
34
Safer writing
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;
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;
}
Socket example
35
Safer writing
Not all data may be sent at
once
TCP takes as much as it wants
to
Try to send again
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
• 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
Set the socket in nonblocking mode …
… and use select
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
36
Safer writing
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;
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;
}
Socket example
37
Safer writing
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;
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 );
}
Socket example
38
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 in
setsockopt( 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
39
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
Socket example
40