Programming with Sockets Manolis Surligas October 30, 2014

Programming with Sockets Manolis Surligas  October 30, 2014
Programming with Sockets
Manolis Surligas
[email protected]
Computer Science Department, University of Crete
October 30, 2014
Programming with Sockets
1 / 27
Goal of this lab
Learn to create programs that communicate over a network
Create TCP and UDP sockets using the POSIX Socket API
Handle properly data
Programming with Sockets
2 / 27
The POSIX Socket API
What is POSIX?
Portable Operating System Interface, is a family of standards
specified by the IEEE for maintaining compatibility between
operating systems.
There are several Sockets implementations (e.g Berkeley,
BSD)
POSIX Socket API, provides a cross-platform and reliable way
for network and inter-process communication
Programming with Sockets
3 / 27
What is a Socket?
Socket is an endpoint of communication between two
processes
Two basic types of sockets:
UNIX sockets
Network sockets
Processes read and write data to the sockets in order to
communicate
Programming with Sockets
4 / 27
What is a Socket?
Socket
Programming with Sockets
5 / 27
Transport Layer
Transport layer is responsible for providing end-to-end data
transfer between two hosts
Two main protocols are used:
TCP
UDP
Programming with Sockets
6 / 27
Transport Layer: TCP
Connection-oriented communication
Reliable, in-order and error free data delivery
Flow-control, congestion avoidance
Programming with Sockets
7 / 27
Transport Layer: UDP
Connection-less communication
Packets may be lost
Packets may arrive in wrong order
Packets may contain wrong data
There is no guaranty that packets sent will reach their
destination
Used when low latency is critical (e.g VoIP, streaming, e.t.c.)
Programming with Sockets
8 / 27
Creating a Socket
Prototype
#i n c l u d e <s y s / t y p e s . h>
#i n c l u d e <s y s / s o c k e t . h>
i n t s o c k e t ( i n t domain , i n t t y p e , i n t p r o t o c o l ) ;
socket() creates a socket of a certain domain, type and
protocol specified by the parameters
Possible domains:
AF INET for IPv4 internet protocols
AF INET6 for IPv6 internet protocols
Possible types:
SOCK STREAM provides reliable two way connection-oriented
byte streams (TCP)
SOCK DGRAM provides connection-less, unreliable messages
of fixed size (UDP)
protocol depends on the domain and type parameters. In
most cases 0 can be passed
Programming with Sockets
9 / 27
Creating a Socket
SOCK STREAM
Sockets of this type are full-dublex data streams that do not rely
on a known data length. Before sending or receiving the socket
must be in a connected state. To send and receive data, send()
and recv() system calls may be used. By default, socket of this
type are blocking, meaning that a call of recv() may block until
data arrive from the other side. At the end, close() should be used
to properly indicate the end of the communication session.
SOCK DGRAM
This kind of sockets allowing to send messages of a specific size
without the guarantee that they will be received from the other
side. To send and receive messages sendto() and recvfrom() calls
may be used.
Programming with Sockets
10 / 27
TCP: Creating the socket
Lets try to create our first TCP socket!
i n t sock ;
i f ( ( s o c k = s o c k e t ( AF INET , SOCK STREAM , IPPROTO TCP ) ) == −1){
p e r r o r ( ” o p e n i n g TCP l i s t e n i n g s o c k e t ” ) ;
e x i t ( EXIT FAILURE ) ;
}
Always check for errors! Using perror() printing a useful and
meaningful message is very easy!
Opening a TCP socket is exactly the same for both server and
client side
Programming with Sockets
11 / 27
Bind a Socket
Prototype
#i n c l u d e <s y s / s o c k e t . h>
i n t bind ( i n t socket , const s t r u c t sockaddr ∗ address ,
socklen t address len );
bind() assigns an open socket to a specific network interface
and port
bind() is very common in TCP servers because they should
waiting for client connections at specific ports
Programming with Sockets
12 / 27
TCP: Bind the socket
struct sockaddr in sin ;
memset(& s i n , 0 , s i z e o f ( s t r u c t s o c k a d d r i n ) ) ;
s i n . s i n f a m i l y = AF INET ;
s i n . s i n p o r t = htons ( l i s t e n i n g p o r t ) ;
s i n . s i n a d d r . s a d d r = h t o n l (INADDR ANY ) ;
i f ( b i n d ( s o c k , ( s t r u c t s o c k a d d r ∗)& s i n ,
s i z e o f ( s t r u c t s o c k a d d r i n ) ) == −1){
p e r r o r ( ”TCP b i n d ” ) ;
e x i t ( EXIT FAILURE ) ;
}
Always reset the struct sockaddr in before use
Addresses and ports must be assigned in Network Byte
Order
INADDR ANY tells the OS to bind the socket at all the
available network interfaces
Programming with Sockets
13 / 27
Listening for incoming connections
Prototype
int
l i s t e n ( i n t socket , i n t backlog ) ;
After binding to a specific port a TCP server can listen at this
port for incoming connections
backlog parameter specifies the maximum possible
outstanding connections
Clients can connect using the connect() call
Hint!
For debugging you can use the netstat utility! Try:
b a s h $ n e t s t a t −t p
or
bash$ n e t s t a t −l t p
Programming with Sockets
14 / 27
Trivia
Think!
Which of the calls of the previous slides cause data to be
transmitted or received over the network?
Programming with Sockets
15 / 27
Trivia
Think!
Which of the calls of the previous slides cause data to be
transmitted or received over the network? NONE!
Programming with Sockets
16 / 27
TCP: Accepting connections
Prototype
#i n c l u d e <s y s / s o c k e t . h>
i n t accept ( i n t socket , struct sockaddr ∗ r e s t r i c t address ,
socklen t ∗ restrict address len );
accept() is by default a blocking call
It blocks until a connection arrives to the listening socket
On success a new socket descriptor is returned, allowing the
listening socket to handle the next available incoming
connection
The returned socket is used for sending and receiving data
If address is not NULL, several information about the remote
client are returned
address len before the call should contain the size of the
address struct. After the call should contain the size of the
returned structure
Programming with Sockets
17 / 27
TCP: Connecting
Prototype
#i n c l u d e <s y s / s o c k e t . h>
i n t connect ( i n t socket , const s t r u c t sockaddr ∗ address ,
socklen t address len );
Connects a socket with a remote host
Like bind(), zero the contains of address before use and
assign remote address and port in Network Byte Order
If bind() was not used, the OS assigns the socket to all the
available interfaces and to a random available port
Programming with Sockets
18 / 27
TCP: Sending Data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t send ( i n t socket ,
const void ∗ buffer ,
s i z e t length , int f l a g s ) ;
send() is used to send data using a connection oriented
protocol like TCP
Returns the actual number of bytes sent
Always check the return value for possible errors or to handle
situations where the requested buffer did not sent completely
Question!
Does this call block?
Programming with Sockets
19 / 27
TCP: Sending Data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t send ( i n t socket ,
const void ∗ buffer ,
s i z e t length , int f l a g s ) ;
send() is used to send data using a connection oriented
protocol like TCP
Returns the actual number of bytes sent
Always check the return value for possible errors or to handle
situations where the requested buffer did not sent completely
Question!
Does this call block? YES!
Programming with Sockets
19 / 27
TCP: Receiving Data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t recv ( i n t socket , void ∗ buffer ,
s i z e t length , int f l a g s ) ;
recv() is by default a blocking call that receives data from a
connection-oriented opened socket
length specifies the size of the buffer and the maximum
allowed received data chunk
Returns the number of bytes received from the network
recv() may read less bytes than length parameter specified,
so use only the return value for your logic
If you do not want to block if no data are available, use
non-blocking sockets (hard!) or poll()
Programming with Sockets
20 / 27
TCP Overview
In high society, TCP is more welcome than UDP. At least it knows
a proper handshake.
Programming with Sockets
21 / 27
UDP: Creating the socket
Creating a UDP socket is quite the same as with TCP
i n t sock ;
i f ( ( s o c k = s o c k e t ( AF INET , SOCK DGRAM, IPPROTO UDP ) ) == −1){
p e r r o r ( ” o p e n i n g UDP s o c k e t ” ) ;
e x i t ( EXIT FAILURE ) ;
}
Only type and protocol parameters are different
bind() is also exactly the same for UDP too
Programming with Sockets
22 / 27
UDP: Connection-less
UDP is connection-less!!!
No need to call accept() or connect()!!!
Programming with Sockets
23 / 27
UDP: Receiving data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t recvfrom ( i n t socket , void ∗ r e s t r i c t buffer ,
s i z e t length , int flags ,
struct sockaddr ∗ r e s t r i c t address ,
socklen t ∗ restrict address len );
length specifies the length of the buffer in bytes
address if not NULL, after the call should contain information
about the remote host
address len is the size of the struct address
Returns the number of bytes actually read. May be less that
length
Programming with Sockets
24 / 27
UDP: Problems at receiving
Have in mind that recvfrom() is a blocking call
How you can probe if data are available for receiving?
Programming with Sockets
25 / 27
UDP: Problems at receiving
Have in mind that recvfrom() is a blocking call
How you can probe if data are available for receiving?
Use poll()
Programming with Sockets
25 / 27
UDP: Problems at receiving
Have in mind that recvfrom() is a blocking call
How you can probe if data are available for receiving?
Use poll()
What if the message sent is greater that your buffer?
Programming with Sockets
25 / 27
UDP: Problems at receiving
Have in mind that recvfrom() is a blocking call
How you can probe if data are available for receiving?
Use poll()
What if the message sent is greater that your buffer?
Use recvfrom() in a loop with poll()
Programming with Sockets
25 / 27
UDP: Sending data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t s e n d t o ( i n t s o c k e t , c o n s t v o i d ∗ message ,
s i z e t length , int flags ,
const s t r u c t sockaddr ∗ dest addr ,
socklen t dest len );
length is the number of the bytes that are going to be sent
from buffer message
dest addr contains the address and port of the remote host
Returns the number of bytes sent. May be less that length so
the programmer should take care of it
Programming with Sockets
26 / 27
UDP: Sending data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t s e n d t o ( i n t s o c k e t , c o n s t v o i d ∗ message ,
s i z e t length , int flags ,
const s t r u c t sockaddr ∗ dest addr ,
socklen t dest len );
length is the number of the bytes that are going to be sent
from buffer message
dest addr contains the address and port of the remote host
Returns the number of bytes sent. May be less that length so
the programmer should take care of it
Trivia!
Does sendto() block?
Programming with Sockets
26 / 27
UDP: Sending data
Prototype
#i n c l u d e <s y s / s o c k e t . h>
s s i z e t s e n d t o ( i n t s o c k e t , c o n s t v o i d ∗ message ,
s i z e t length , int flags ,
const s t r u c t sockaddr ∗ dest addr ,
socklen t dest len );
length is the number of the bytes that are going to be sent
from buffer message
dest addr contains the address and port of the remote host
Returns the number of bytes sent. May be less that length so
the programmer should take care of it
Trivia!
Does sendto() block? NO!
Programming with Sockets
26 / 27
Endianness
Networks are heterogenous with many
different OS’s, architectures, etc
Endianess is a serious problem when sending
data to other hosts
When sending entities that are greater that a
byte, always convert them in Network Byte
Order
By default Network Byte Order is Big-Endian
Use nthohs(), nthohs(), htonl(), ntohl()
Programming with Sockets
27 / 27
Endianness
Networks are heterogenous with many
different OS’s, architectures, etc
Endianess is a serious problem when sending
data to other hosts
When sending entities that are greater that a
byte, always convert them in Network Byte
Order
By default Network Byte Order is Big-Endian
Use nthohs(), nthohs(), htonl(), ntohl()
Trivia!
When sending large strings do we have to convert
in Network Byte Order?
Programming with Sockets
27 / 27
Endianness
Networks are heterogenous with many
different OS’s, architectures, etc
Endianess is a serious problem when sending
data to other hosts
When sending entities that are greater that a
byte, always convert them in Network Byte
Order
By default Network Byte Order is Big-Endian
Use nthohs(), nthohs(), htonl(), ntohl()
Trivia!
When sending large strings do we have to convert
in Network Byte Order? NO!
Programming with Sockets
27 / 27
Useful man pages
socket(7)
ip(7)
setsockopt(3p)
tcp(7)
udp(7)
Programming with Sockets
28 / 27
Questions??
Programming with Sockets
29 / 27
Was this manual useful for you? yes no
Thank you for your participation!

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

Download PDF

advertisement