Download Introduction - Universität Basel | Informatik

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Parallel port wikipedia , lookup

Dynamic Host Configuration Protocol wikipedia , lookup

AppleTalk wikipedia , lookup

Cracking of wireless networks wikipedia , lookup

Zero-configuration networking wikipedia , lookup

Remote Desktop Services wikipedia , lookup

Lag wikipedia , lookup

Transcript
Computernetzwerke und Sicherheit (CS221)
4. Socket Programming in C
4. März 2011
omas Meyer (basierend auf einem Foliensatz von Christophe Jelger)
Departement Mathematik und Informatik, Universität Basel
Introduction
What is a socket?
❖
❖
❖
A socket is a bi-directional communication abstraction
(called association) between two processes.
A socket is the endpoint of a communication.
Sockets is an Application Programming Interface (API) for
InterProcess Communication (IPC)
process 1
socket
e.g. web browser
process 2
socket
e.g. web server
(Mozilla, Internet Explorer)
CS221 — FS11 — 4. Socket Programming
2
Introduction
ere are may types of sockets
❖
SOCK_STREAM: TCP (connection oriented, guaranteed delivery)
❖
SOCK_DGRAM: UDP (datagram-based communication)
❖
❖
SOCK_RAW: allows access to the network layer.
is can be used to build ICMP messages or custom IP packets.
SOCK_PACKET: allows access to the link-layer (e.g. Ethernet).
is can be used to build entire frames
(e.g. to build a user-space router).
CS221 — FS11 — 4. Socket Programming
3
Introduction
ere are many domains and (P)rotocol (F)amilies to deal with
❖
PF_INET: IP version 4 (32-bit addresses)
❖
PF_INET6: IP version 6 (128-bit addresses)
❖
PF_UNIX: interprocess communication on the local machine
❖
PF_APPLETALK: Appletalk networks
❖
PF_IPX: Novell Netware networks
❖
...
❖
PF_ROUTE: access to routing tables (*BSD systems)
CS221 — FS11 — 4. Socket Programming
4
Introduction
192.168.1.119
131.152.227.232
HTTP server
Port 80
Web browser
Port 32816
PF_INET, SOCK_STREAM
(IPv4)
(TCP)
Want to check active sockets on your machine?
# netstat -ap -A inet (or inet6, or unix)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address
tcp
0 *:ipp
*:*
tcp
0 192.168.1.119:32816
www.cs.unibas.ch:www
tcp
0 192.168.1.119:32815
www.cs.unibas.ch:www
tcp
0 192.168.1.119:32769
clarinet.u-strasb:imaps
tcp
0 *:bootpc
*:*
udp
0 *:ipp
*:*
udp
0 *:icmp
*:*
State
PID/Program name
LISTEN
1437/cupsd
ESTABLISHED1621/mozilla-thunde
ESTABLISHED1621/mozilla-thunde
ESTABLISHED1621/mozilla-thunde
1271/dhclient
1437/cupsd
1720/vmnet-natd
CS221 — FS11 — 4. Socket Programming
5
Socket creation
int socket (int domain, int type, int protocol);
domain:
type:
protocol:
PF_INET, PF_INET6, PF_UNIX, ...
SOCK_DGRAM, SOCK_STREAM,...
0=default, or
IPPROTO_UDP, IPPROTO_TCP, ...
e returned value is a descriptor (i.e., an integer value that
uniquely identifies the socket among other descriptors such as
sockets, files, pipes, etc.)
Example: int my_socket;
my_socket = socket(AF_INET, SOCK_STREAM, 0);
CS221 — FS11 — 4. Socket Programming
6
Socket address configuration
struct sockaddr_in {
short int
sin_family;
unsigned short int sin_port;
struct in_addr
sin_addr;
unsigned char
sin_zero[8];
};
struct in_dadr {
unsigned long s_addr;
};
/*
/*
/*
/*
domain*/
port number */
IP address */
padding with zeros */
❖
Purpose of structure: easy access to socket parameters
❖
Basic structure: sockaddr
❖
But one should always use the appropriate sockaddr_XXX
when accessing a specific structure type (e.g. sockaddr_in)
sockaddr
family
sockaddr_in
family
blob
port
addr
zero
CS221 — FS11 — 4. Socket Programming
7
Watch the conversions!!!
Convert multibyte integers
❖
50966 in decimal = c734 in hexadecimal
❖
there are two ways to encode this number in 32 bits:
• 34-c7-00-00 = host byte order (little-endian, Intel)
• 00-00-c7-34 = host byte order (big-endian, Motorola, IBM)
memory n...n+3
• 00-00-c7-34 = network byte order (big-endian, for all machines!)
❖
❖
sin_port
and sin_addr MUST be in network byte order
When building a packet (SOCK_RAW or SOCK_PACKET),
all data fields must be in network byte order!
CS221 — FS11 — 4. Socket Programming
8
Integer conversion functions
❖
htonl
host to network long (to convert a long integer (32 bit)
from host to network byte order, before tx)
❖
htons
host to network short (to convert a short integer (16 bit)
from host to network byte order, before tx)
❖
ntohl
network to host long (after rx)
❖
ntohs
network to host short (after rx)
Caution: Don’t convert chars!
Example: struct
sockaddr_in webyahooAddr;
webyahooAddr.sin_family = AF_INET;
webyahooAddr.sin_port = htons(80);
webyahooAddr.sin_addr.s_addr = inet_addr(“217.12.3.11”);
memset(&webyahooAddr.sin_zero, ‘\0’, 8);
CS221 — FS11 — 4. Socket Programming
9
Datagram-based communication
Function calls with UDP (SOCK_DGRAM)
station 1
station 2
socket()
socket()
bind()
bind()
sendto()/recvfrom()
close()
data
sendto()/recvfrom()
close()
CS221 — FS11 — 4. Socket Programming
10
Binding of the socket (to an address)
Bind = Assign IP address and port number to socket
Example:
int mySock;
struct sockaddr_in locAddr;
mySock = socket(PF_INET, SOCK_STREAM, 0);
/* or SOCK_DGRAM */
locAddr.sin_family = AF_INET;
locAddr.sin_port = htons(0);
/* let the system choose */
locAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* any addr of machine */
memset(&locAddr, ‘\0’, 8);
bind(mySock, (struct sockaddr*)&locAddr, sizeof(locAddr));
CS221 — FS11 — 4. Socket Programming
11
Binding of the socket (to an address)
Read-back auto values
❖
When calling bind() with sin_port=0, the value chosen by
the system is not saved in the structure.
❖
We must use getsockname() to update the structure.
Example:
int length;
getsockname(mySock, (struct sockaddr*)&locAddr, &length);
/* note: length is an output argument; we have to pass its address */
/* the port number is now updated and can be displayed:
but remember to convert to host byte order! */
printf(“Port chosen by the system is %d, ntohs(locAddr.sin_port));
CS221 — FS11 — 4. Socket Programming
12
Stream-based communication
Walk-through example: TCP Echo Server
client
socket()
server
bind()
socket()
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
CS221 — FS11 — 4. Socket Programming
13
Echo server: Create socket
/* create socket for incoming connections */
int srvSock = socket(PF_INET, SOCK_STREAM, 0);
client
socket()
bind()
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
CS221 — FS11 — 4. Socket Programming
14
Echo server: Bind local address
struct sockaddr_in srvAddr;
srvAddr.sin_family = AF_INET;
/* IPv4 address
srvAddr.sin_port = htons(8080);
/* local server port
srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* any interf.
memset(&srvAddr.sin_zero, ‘\0’, 8);
/* padding
*/
*/
*/
*/
bind(srvSock, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
client
socket()
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
CS221 — FS11 — 4. Socket Programming
15
Echo server: Listen to incoming connections
/* listen for incoming connections */
listen(srvSock, MAXPENDING);
client
socket()
bind()
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
CS221 — FS11 — 4. Socket Programming
16
Echo server: Accept incoming connections
for (;;)
{
struct sockaddr_in cliAddr;
/* client address */
int cliAddrLen = sizeof(cliAddr);
int cliSock;
/* socket for comm. to client */
cliSock = accept(srvSock, (struct sockaddr*)&cliAddr, &cliAddrLen);
client
socket()
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
17
Echo Server: Accept incoming connections
Server is now blocked, waiting for an incoming connection:
client
socket()
bind()
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
18
Echo client: Create socket
/* create TCP socket for outgoing connection */
int cliSock = socket(PF_INET, SOCK_STREAM, 0);
client
socket()
cliSock
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
19
Echo Client: Bind local address (optional)
struct sockaddr_in cliAddr;
cliAddr.sin_family = AF_INET;
/* IPv4
cliAddr.sin_port = 0;
/* any port
cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* any
memset(&srvAddr.sin_zero, ‘\0’, 8);
/*
address
is fine
interf.
padding
*/
*/
*/
*/
bind(cliSock, (struct sockaddr*)&cliAddr, sizeof(cliAddr));
client
socket()
bind()
cliSock
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
20
Echo Client: Connect to server
struct sockaddr_in srvAddr;
srvAddr.sin_family = AF_INET;
/* IPv4 address
srvAddr.sin_port = htons(8080);
/* server port
srvAddr.sin_addr.s_addr = inetaddr(“1.2.3.4”);
/* server IP
memset(&srvAddr.sin_zero, ‘\0’, 8);
/* padding
*/
*/
*/
*/
connect(cliSock, (struct sockaddr*)&srvAddr, sizeof(srvAddr));
client
socket()
cliSock
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
21
Echo Server: Accept incoming connections
cliSock = accept(srvSock, (struct sockaddr*)&cliAddr, &cliAddrLen);
Blocking call accept() returns
cliSock is the socket descriptor for communication with the client
client
socket()
bind()
cliSock
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
22
Echo Client: Send a message and wait for reply
char msg[] = “This is a test.”;
send(cliSock, msg, strlen(msg), 0);
/* wait for reply by calling recv() (not shown here) */
client
socket()
cliSock
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
23
Echo Server: Receive and send same messages
#define BUFSIZE 32
char buf[BUFSIZE];
int bytesRecv;
bytesRecv = recv(cliSock, buf, BUFSIZE, 0);
while (bytesRecv > 0) /* zero indicates end of transmission */
{
send(cliSock, buf, bytesRecv, 0); /* echo */
bytesRecv = recv(cliSock, buf, BUFSIZE, 0);
}
client
socket()
bind()
cliSock
server
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
24
Echo Server: Close connection (and accept next)
for (;;)
{
...
cliSock = accept(srvSock, (struct sockaddr*)&cliAddr, &cliAddrLen);
...
close(cliSock);
}
client
socket()
cliSock
server
bind()
socket()
srvSock
bind()
listen()
connect()
accept()
send()/recv()
send()/recv()
close()
close()
cliSock
CS221 — FS11 — 4. Socket Programming
25
TCP Socket Features
❖
❖
❖
e client must know the server’s address/port.
e server must only know its own port!
Streaming socket:
Transmission/Reception of a byte “stream”
❖ No correlation between bytes and segments (packets).
Segmentation of the byte stream is out of the user’s control
(due to TCP’s Flow Control)
❖
client
send(“This is a test”);
recv(“Hello world”);
server
recv()
recv()
recv()
send()
send()
->
->
->
->
->
“This i”;
“s a te”;
“st”;
“Hello “
“world”;
CS221 — FS11 — 4. Socket Programming
26
TCP Socket Features
❖
❖
close() is used to terminate a connection
analogous to EOF (end-of-file)
client
server
send(...);
while (recv(...) > 0) {
send(...)
}
close();
close();
❖
Caution: Does not work with datagram socket
❖ e.g. UDP
❖ not connection-oriented = no close-notification
CS221 — FS11 — 4. Socket Programming
27
Blocking calls
Be careful: calls are blocking!
❖
A call to recv(), send(), recvfrom(), and sendto() is
by default a blocking call.
Example:
recvfrom(...);
sendto(...);
/* call blocks until a message is received */
e program will not be able to send if it does not
receive anything!
❖
❖
Solution 1: use the select() function
Solution 2: multi-threaded applications
CS221 — FS11 — 4. Socket Programming
28
The select() function
❖
❖
Used to monitor a set of descriptors
(e.g. sockets, files, pipes, stdin).
select() blocks until an event on the observed
descriptors occurs:
If we check a set in order to trigger read operations,
select() returns the set that has data ready to be read.
❖ If select() is used in a loop, the initial set of descriptors
must then always be initialized properly before re-calling
❖
select()
❖
e blocking behavior of select() can be changed
by specifying a timeout value (last function argument).
CS221 — FS11 — 4. Socket Programming
29
Using the select() function
Example: a server wants to check two sockets for data to read
/* the two socket descriptors are sock1 and sock2;
let sockmax = (sock1 > sock2 ? sock1 : sock2) */
/* we first need a set of file descriptors */
fd_set readfds, backup;
/* we initialize the set and add sock1 and sock2 to it */
FD_ZERO(&readfds);
FD_SET(sock1, &readfds);
FD_SET(sock2, &readfds);
backup = readfds;
/* used to save the original state */
for (;;)
{
select(sockmax, &readfds, NULL, NULL, NULL);
if (FD_ISSET(sock1, &readfds))
recv(sock1, buf, MAX_LEN, 0);
if (FD_ISSET(sock2, &readfds))
recv(sock2, buf, MAX_LEN, 0);
readfds = backup;
/* set readfds to initial state */
CS221 — FS11 — 4. Socket Programming
}
30
Multithreaded server
❖
Spawn a new thread for each accepted connection
for (;;)
{
cliSock = accept(srvSock, (struct sockaddr *)&cliAddr, &cliAddrLen);
pid = fork();
if (pid == 0) /* child thread */
{
close(srvSock);
dostuff(cliSock);
exit(0);
}
else
/* parent thread */
{
close(cliSock);
/* continue in while loop: accept next connection... */
}
}
CS221 — FS11 — 4. Socket Programming
31
Handle errors!
❖
❖
Socket programming can easily lead to many errors.
It is mandatory to check for errors!
(for clarity, this is not done in these slides)
Example:
if (bind(mySock, (struct sockaddr*)&sockAddr, sizeof(sockaddr) < 0)
{
perror(“Bind: “); /* prints out an explicit error message */
exit(-1);
}
❖
Use perror() with all calls! (accept, connect, ...)
CS221 — FS11 — 4. Socket Programming
32
Summary
❖
❖
❖
❖
❖
❖
❖
❖
e socket API provides user-level abstractions for
communication associations.
One API for different communication types
streaming, datagram-oriented,
connection-oriented, connection-less
and different protocols
e.g. UDP, TCP, interprocess communiction
socket(), accept() “creates” new socket descriptor
close() “destroys” the descriptor
bind() configures/binds an address to a socket
connect(), accept() to establish a connection-oriented session
send()/recv() to send over pre-configured socket
sendto()/recvfrom() to configure remote side on-the-fly
CS221 — FS11 — 4. Socket Programming
33