Programming with TCP/IP
Download
Report
Transcript Programming with TCP/IP
Programming with TCP/IP
by
Armin R. Mikler
1
Client Server Computing
Although the Internet provides a basic
communication service, the protocol
software cannot initiate contact with, or
accept contact from, a remote computer.
Instead, two application programs must
participate in any communication with one
application initiates communication and the
one accepts it.
2
In network applications, a SERVER
application waits passively for contact
after informing local protocol software
that a specific type of message is
expected, while a CLIENT application
initiates communication actively by sending
a matched type of message.
3
Identifying A Particular
Service
Transport protocols assign each service a
unique identifier.
Both client and server specify the service
identifier; protocol software uses the
identifier to direct each incoming request
to the correct server.
In TCP/IP, TCP uses 16-bit integer values
known as protocol port numbers to identify
services.
4
Concurrent Server
Concurrent execution is fundamental to servers
because concurrency permits multiple clients to
obtain a given service without having to wait for
the server to finish previous requests.
In concurrent server designs, the server creates a
new thread or process to handle each client.
Transport protocols assign an identifier to each
client as well as to each service.
Protocol software on the server’s machine uses
the combination of client and server identifiers to
choose the correct copy of a concurrent server.
5
The Socket API
The interface between an application
program and the communication protocols
in an operating system (OS) is known as
the Application Program Interface or API.
Sockets provide an implementation of the
SAP (Service Access Point) abstraction at
the Transport Layer in the TCP/IP protocol
suite, which is part of the BSD Unix.
6
A socket library can provide applications with a
socket API on an operating system that does not
provide native sockets (e.g. Windows 3.1). When an
application calls one of the socket procedures,
control passes to a library routine that makes one
or more calls to the underlying OS to implement
the socket function.
A socket may be thought of as a generalization of
the BSD Unix file access mechanism (open-readwrite-close) that provides an end-point for
communication.
7
When an application creates a socket, the
application is given a small integer descriptor used
to reference the socket. If a system uses the
same descriptor space for sockets and other I/O,
a single application can be used for network
communication as well as for local data transfer.
An application must supply many details for each
socket by specifying many parameters and options
(e.g. an application must choose a particular
protocol, provide address of remote machine,
specify whether it is a client or server, etc.)
8
To avoid having a single socket function
with separate parameters for each options,
designers of the socket API chose to
define many functions, each with a few
parameters.
9
Functions needed
Specify local and remote communication
endpoints
Initiate a connection
Wait for incoming connection
Send and receive data
Terminate a connection gracefully
Error handling
10
Server
(connection-oriented protocol)
socket()
bind()
Socket system calls for
connection-oriented
protocol
listen()
accept()
blocks until connection
from client
Client
socket()
connection establishment connect()
read()
data (request)
write()
process request
write()
data (reply)
read()
11
Server
(connectionless protocol)
socket()
Socket system calls for
connectionless protocol
bind()
recvfrom()
Client
Not necessary
in UDP!!
blocks until data
received from client
socket()
bind()
data (request)
sendto()
process request
sendto()
data (reply)
revfrom()
12
Data communication between two hosts on
the Internet require the five components
of what is called an association to be
initialized: {protocol,local-addr, localprocess, foreign-addr, foreign-process}
The different system calls for sockets
provides values for one or more of these
components.
13
Socket system call
The first system call any process wishing to do
network I/O has to call is the socket system call.
int sockfd = socket (int family, int type, int
protocol)
Examples of Family include:
AF_UNIX
AF_INET
Examples of Type include
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
14
The protocol argument is typically zero,
but may be specified to request an actual
protocol like UDP, TCP, ICMP, etc.
The socket system call just fills in one
element of the five-tuple we’ve looked at the protocol. The remaining are filled in by
the other calls as shown in the figure.
15
local_addr,
protocol local_process
Connection-Oriented Server
socket() bind()
Connection-oriented Client
socket()
foreign_addr,
foreign_process
accept()
connect()
Connectionless Server
socket() bind()
recvfrom()
Connectionless Client
socket() bind()
sendto()
16
Specifying an Endpoint Address
Remember that the sockets API is generic
There must be a generic way to specify endpoint addresses
TCP/IP requires an IP address and a port number for each
endpoint address.
Other protocol suites(families) may use other schemes.
Generic socket addresses
(The C function that make up the sockets API expect structures of type
sockaddr.)
:
struct sockaddr {
unsigned short
sa_family;
//specifies the address type
char
sa_data[14];
//specifies the address value
};
17
AF_INET--TCP/IP address
For AF_INET we need:
16 bit port number
32 bit IP address (IPv4 only)
struct sockaddr_in{
short
sin_family;
unsigned short
sin_port;
struct in_addr
sin_addr;
char
sin_zero[8];
};
how these fields to be set and interpreted?
18
Network Byte Order Functions
Example:
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(9999);
sin.sin_addr.s_addr = inet_addr;
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohl(unsigned long);
19
Bind System Call
The bind system call assigns an address to
an unnamed socket. Example:
int bind(int sockfd, struct sockaddr_in
*myaddr, int addrlen)
20
What is bind used for ?
Servers (both connection oriented and connectionless)
NEED to register their well-known address to be able to
accept connection requests.
A client can register a specific address for itself.
A connectionless client NEEDS to assure that it is bound
to some unique address, so that the server has a valid
return address to send its responses to – However, it
does not have to bind to a particular port! WHY?
21
The bind system call provides the values for the
local_addr and local_process elements in the
five_tuple in an association.
An address for the Internet domain sockets is a
combination of a hostname and a port number, as
shown below:
struct sockaddr_in {
short sin_family ; /*typically AF_INET*/
u_short sin_port; /* 16 bit port number, network byte ordered */
struct in_addr sin_addr ; /* 32 bit netid/hostid, network byte
ordered */
char sin_zero[8]; /* unused*/
}
22
Connect/Listen/Accept System
Calls
Connect
A client process connects a socket descriptor
after a socket system call to establish a
connection with the server.
int connect(int sockfd, struct sockaddr_in
*servaddr, int addrlen)
For a connection-oriented client, the connect
(along with an accept at the server side) assigns
all four addresses and process components of
the association.
23
Listen
The listen system call is used by a connectionoriented server to indicate it is willing to
receive connections.
int listen(int socket, int qlength)
allows servers to prepare a socket for incoming
connections
puts the socket in a passive mode ready to accept
connections
informs the OS that the protocol software should
enqueue multiple simultaneous requests that arrive at the
socket
applies only to sockets that have selected reliable stream
delivery service
24
Accept
After the connection-oriented server executes
a listen, it waits for connection requests from
client(s) in the accept system call, e.g.,
newsockfd = accept(sockfd, peer, addrlen)
needs to wait for a connection
blocks until a connection request arrives
addrlen is a pointer to an integer;
• when a request arrives , the system fills in argument
addr with the address of the client that has placed
the request and sets addrlen to the length of the
address.
• system creates a new socket, returns the new socket
descriptor
25
accept returns a new socket descriptor, which
has all five components of the association
specified - three (protocol, local addr,
local_process) are inherited from the existing
sockfd (which however has its foreign address
and process components unspecified, and hence
can be re-used to accept another request. This
scenario is typical for concurrent servers.
26
Sending and Receiving Data
Here’s how you might read from a socket:
num_read = read(sockfd, buff_ptr, num_bytes)
And here’s how you read from an open file
descriptor in Unix:
num_read
= read(fildes, buff_ptr, num_bytes)
There are other ways (with different
parameters) to send and receive data:
read, readv, recv, recvfrom, recvmsg to
receive data through a socket; and write,
writev, send, sendto, sendmsg to send data
through a socket.
27
sendto()--UDP Sockets
int sendto(int socket, char *buffer, int length,
int
flags, struct
sockaddr *destination_address, int
address_size);
For example:
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(12345);
sin.sin_addr.s_addr = inet_addr("128.227.22.43");
char *msg = "Hello, World";
sendto(s, msg, strlen(msg)+1, 0, (struct sockaddr *)sin,
sizeof(sin));
28
recvfrom()--UDP Sockets
Int recvfrom(int socket, char *buffer, int
length,
int flags, struct
sockaddr *sender_address, int
*address_size)
For example:
struct sockaddr_in sin;
char msg[10000];
int ret;
int sin_length;
sin_length = sizeof(sin);
ret = recvfrom(s, msg, 10000, 0, (struct sockaddr *)sin,
&sin_length);
printf("%d bytes received from %s (port %d)\n", ret,
inet_ntoa(sin.sin_addr), sin.sin_port);
29
send() and recv() -- TCP Sockets
int send(int s, const char *msg, int len, int
flags)
connected socket
argument flags controls the transmission.
• allows the sender to specify that the message should be sent
out-of- band messages correspond to TCP’s urgent data
• allows the caller to request that the message be sent without
using local routine tables (take control of routine)
int recv(int s, char *buf, int len, int flags)
connected socket
argument flags allow the caller to control the
reception
• look ahead by extracting a copy of the next incoming message
without removing the message from the socket
30
close() and shutdown()
close(int socket)
For UDP sockets, this will release the ownership
on the local port that is bound to this socket
For TCP, this will initiate a two-way shutdown
between both hosts before giving up port
ownership.
shutdown(int socket, int how)
f the how field is 0, this will disallow further
reading (recv) from the socket.
If the how field is 1, subsequent writes (send)
will be disallowed. The socket will still need to be
passed to close.
31
Relationship Between Sockets
and File Descriptors
Socket handles are integer values. In UNIX, socket handles can be
passed to most of the low-level POSIX I/O functions.
read(s, buffer, buff_length); //s could be a file descriptor too
write(s, buffer, buff_length) ;
Calling read on an open socket is equivalent to recv and recvfrom
if the socket is UDP, then information about the sender of the
datagram will not be returned
Similarly the write function call is equivalent to send and sendto
UDP sockets may call connect to use send and write
use the socket library functions instead of the file I/O equivalents.
32
Utility Functions
unsigned int inet_addr(char *str)
str represents an IP address(dotted-quad notation);
inet_addr will return it's equivalent 32-bit value in
network byte order.
This value can be passed into the sin_addr.s_addr field of
a socketaddr_in structure
-1 is returned if the string can not be interpreted
char *inet_ntoa(struct in_addr ip)
Converts the 32-bit value which is assumed to be in
network byte order and contained in ip to a string
The pointer returned by inet_ntoa contains this string.
However, subsequent calls to inet_ntoa will always return
the same pointer, so copying the string to another buffer
is recommended before calling again.
33
Utility Functions ( cont’d )
int gethostname(char *name, int length)
Copies the name (up to length bytes) of the
hostname of the local computer into the
character array pointed to by name
struct hostent *gethostbyname(char
*strHost)
int select (int nfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds,
const struct timeval *timeout)
34
Other Socket API
JAVA
platform independence;
Java API for network programming
• java.net Pakage
• classes
–
–
–
–
–
–
Socket
ServerSocket
DatagramSocket
DatagramPacket
InetAddress
etc.
compile and run
35
Others
Include files
#include <sys/types.h>;
#include <arpa/inet.h>;
#include <signal.h>;
#include <errno.h;
#include <memory.h>;
#include <sys/socket.h>;
#include <netdb.h>;
#include <stdio.h>;
#include <sys/time.h>;
#include <netinet/in.h>;
#include <unistd.h>;
#include <fcntl.h>;
#include <stdlib.h>;
Compiling and Linking
Under most versions of UNIX (Linux, BSD, SunOS, IRIX)
compiling is done as usual:
• gcc my_socket_program.c -o my_socket_program
Solaris:
• cc my_socket_program.c -o my_socket_program -lsocket -lnsl
Programming tips
always check the return value for each function call
consult the UNIX on-line manual pages ("man") for a complete description
36
Summary
Network Application Programming Interface
(API)
TCP/IP basic
UNIX/C Sockets
socket() ; bind() ; connect() ; listen() ; accept() ;
sendto() ; recvfrom(); send() ; recv() ; read() ;
write();
some utility functions
Java Socket API
37