0% found this document useful (0 votes)
55 views53 pages

Lecture 2

The document provides information about TCP and UDP programming in C including: 1. It outlines the TCP and UDP socket API functions for clients and servers such as socket(), connect(), bind(), listen(), accept(), send(), recv(), sendto(), and recvfrom(). 2. It describes TCP as a connection-oriented protocol that guarantees data delivery and ordering while UDP is connectionless and does not guarantee delivery. 3. It discusses blocking, non-blocking, and multiplexed I/O and provides an example of a concurrent threaded TCP server.

Uploaded by

Diana Mocanu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views53 pages

Lecture 2

The document provides information about TCP and UDP programming in C including: 1. It outlines the TCP and UDP socket API functions for clients and servers such as socket(), connect(), bind(), listen(), accept(), send(), recv(), sendto(), and recvfrom(). 2. It describes TCP as a connection-oriented protocol that guarantees data delivery and ordering while UDP is connectionless and does not guarantee delivery. 3. It discusses blocking, non-blocking, and multiplexed I/O and provides an example of a concurrent threaded TCP server.

Uploaded by

Diana Mocanu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 53

Computer Networks

Adrian Sergiu DARABANT

Lecture 2
TCP Programming API
#include <sys/socket.h>
Client + Server :
int socket (int family, int type, int protocol);

Client:
int connect (int sfd, const struct sockaddr *servaddr, socklen_t addrlen);

Server:
int bind(int sfd, const struct sockaddr *servaddr, socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

Client + Server:
#include <unistd.h>
int close(int sockfd);
Socket Addresses - Generic
struct sockaddr {
   uint8_t sa_len;
   sa_family_t sa_family; /* address family: AF_xxx value */
   char sa_data[14];
};
sa_data is a: (like when using unions)
struct sockaddr_in {
   uint8_t sin_len; /* length of structure (16)*/
   sa_family_t sin_family; /* AF_INET*/
   in_port_t sin_port; /* 16 bit TCP or UDP port number */
   struct in_addr sin_addr; /* 32 bit IPv4 address*/
   char sin_zero[8]; /* not used but always set to zero - remaining to 14*/
};

struct in_addr{
in_addr_t s_addr; /*32 bit IPv4 network byte ordered address*/
};
TCP Programming API
Once a connection is setup:

#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
int write(int sockfd, …..) – works as well

ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
int read(int sockfd,……) – works as well
TCP Programming

Client Server Iterative Example


TCP
Connection-Oriented
 Recv - when RECV return N bytes have been received
 Send – when SEND returns N bytes have successfully delivered to OS
and maybe to destination. Error will be signaled on next operation

Guaranteed data delivery


Guaranteed data ordering delivery
Type = SOCK_STREAM – when creating
socket
Client-Server TCP/IP Apps
Server listens for client’s requests,
executes them and answers.
Server types (from the Comm Point of View)
 Iterative Servers (blocking)
 Concurrent servers (blocking)(fork,
threads)
 Concurrent multiplexed servers. (select)
Concurrent TCP Servers
Servers able to handle multiple clients in
the same time;
Implementation:
 Fork/CreateProcess – independent client
 Threads – interdependent states between
clients
 Select system call
Working with the DNS
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const void *addr, int len, int type);

hostent structure is defined in <netdb.h> as follows:


struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
#define h_addr h_addr_list[0]
-------------------------------------------------------------------------------
Another Approach: getaddrinfo(….), getnameinfo(….)
Concurrent TCP Servers

Example – fork
Little Endian/Big endian
In memory data representation

 Big endian – most significant byte first


 Little endian – least significant byte first
46F4 – Little end. => F4 46
- Big end. => 46 F4
Little Endian/Big endian
Float and double
Float – 4 bytes
31 0
s E E E E E E E E MMMMMMMMMMMMMMMMMMMMMMM

exp mantisa
Float = (sign?-1:1) * 2^exp *1.<mantisa>
Double - 8 bytes

Same endianness as integers


Swapping 8 or more byte entities ?!?
Example Concurrent Threaded Server

The server generates a random number. All connecting


clients send a number to the server. The server
answers with:
•‘S’ – give a smaller number
•‘H’ – give a larger number
•‘G’ – you guessed my number
•‘L’ – you lost. Somebody else guessed !
Write a client server implementation where each client
is informed at the end of its status: winner/looser !
UDP
Connection-Less – datagram oriented
 Recvfrom- N bytes received
 Sendto - N bytes given to the OS/network !!!
No guarantee for datagram delivery
No guarantee for datagram ordering
Type = SOCK_DGRAM – when creating
socket
TCP vs UDP
TCP UDP
Write =>stream of bytes. Write =>packets of bytes.
Read=>reads from the Read=>reads bytes from
stream one packet !
Bytes Not read from stream Not read bytes from a
stay available for next read packet are lost !
Flow: neither party can
overflow the other! Traffic Flow: one party can
is controlled by the OS overflow the other =>lost
packets ! No control !
UDP API
socket(…, SOCK_DGRAM,…)
bind – similar to TCP - has the same
meaning
Data exchange – sendto, recvfrom
close – same meaning as TCP
Remark:
 No listen and accept are required/permitted !
UDP API
ssize_t sendto(int sockfd, const void *buf, size_t len, int
flags, const struct sockaddr *dest_addr, socklen_t addrlen);
Return:
•no of bytes transmitted to the OS/network if positive
•-1 in case of locally detected error (errno set appropriately)
No error signaling for undelivered data !
Data size must fit into a transmission
unit(datagram) < 64Kb or Error !
One sendto operation must be consumed by
exactly one recvfrom operation on the receiver!
UDP API
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
Return:
•no of bytes received from the OS/network and stored into buf
•-1 in case of error (errno set appropriately)
Call blocks until a datagram arrives
If not all data is read in ONE call – the remaining is
discarded
Cannot receive more than the maximul transfer
unit (datagram) size – max. 64 Kb
Socket Options
setsockopt(int s, int level, int optname, void *optval,
socklen_t *optlen)
getsockopt(…..)
man 7 socket/ip/udp/tcp
Optname
SO_REUSEADDR – reuse local addresses – use it to
get rid of the address already in use after you
terminate your TCP/IP app abruptly !
SO_BROADCAST – enables broadcast = one sender –
Universal(all) receiver(s)!
Advanced TCP/IP – I/O Modes

1. Blocking I/O
2. Nonblocking I/O
3. I/O multiplexing (select and poll)
4. Signal driven I/O (SIGIO)
5. Asynchronous I/O (the POSIX
aio_functions)
Network operation steps - READ
1. Waiting for the data to be ready – i.e.
data arrives from the network
2. Copying the data from the kernel to
the process – i.e. copying the data
from the kernel buffer into the
application space.
Blocking I/O Model

Process is
sleeping !
Non-Blocking I/O Model

Process is
active !
Multiplexed I/O Model

Involves using select and poll


Signal I/O Model
Asynchronous I/O Model

• aio_read – asynchronous POSIX read


• Async - Kernel tells us when the operation is complete
• Signal – Kernel tells us when the operation can start !!
Blocking I/O Operations Sequence
Client Server
Write(…) Read(…)
Write(…) ? Read(…)
Read(…) Write(…)

Write(…) Write(…)
Write(…) ? Read(…)
Read(…) Write(…)

Read(…) Read(…)
Write(…) ? Read(…)
Read(…) Write(…)
The select system call
#include <sys/select.h>
#include <sys/time.h>
int select(int maxfd+1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
const struct timeval *timeout);
Returns:
 positive count of ready descriptors
 0 if timeout
 -1 on error

void FD_ZERO(fd_set *fdset); - clear all bits in fdset


void FD_SET(int fd, fd_set *fdset); - turn on the bit for fd in fdset
void FD_CLR(int fd, fd_set *fdset); - turn off the bit for fd in fdset
int FD_ISSET(int fd, fd_set *fdset); - IS the fd ready ?
BE WARNED – select modifies readset,
writeset and exceptset
Conditions for a socket to be ready
Condition Readable Writable Exception
Data to read Y
Read half connection closed Y
New connection (for listen) Y
Space available for writing Y
Write half connection closed Y
Pending error Y Y
TCP- out-of-bound DATA Y
MultiClient Chat Server -1
#include <stdio.h> int fdmax; // maximum file desc. number
#include <stdlib.h> int listener; // listening socket descriptor
#include <string.h> int newfd; // newly accept()ed socket
#include <unistd.h> char buf[256], tmpbuf[256];
#include <sys/types.h> int nbytes, ret;
#include <sys/socket.h> int yes=1; // setsockopt() SO_REUSEADDR
#include <netinet/in.h> int addrlen;
#include <arpa/inet.h> int i, j, crt, int_port,client_count=0;

fd_set master; // master file descriptor list


fd_set read_fds; // temp file descriptor list for
select()
struct sockaddr_in myaddr; // server address
struct sockaddr_in remoteaddr;
MultiClient Chat Server -2
struct sockaddr_in getSocketName(int s, bool local_or_remote) {
struct sockaddr_in addr;
int addrlen = sizeof(addr);
int ret;

memset(&addr, 0, sizeof(addr));
ret = (local_or_remote==true?getsockname(s,(struct sockaddr *)&addr,
(socklen_t*)&addrlen):
getpeername(s,(struct sockaddr *)&addr, (socklen_t*)&addrlen) );
if (ret < 0)
perror("getsock(peer)name");
return addr;
}
MultiClient Chat Server -3
char * getIPAddress(int s, bool local_or_remote) {
struct sockaddr_in addr;
addr = getSocketName(s, local_or_remote);
return inet_ntoa(addr.sin_addr);
}

int getPort(int s, bool local_or_remote) {


struct sockaddr_in addr;
addr = getSocketName(s, local_or_remote);
return addr.sin_port;
}
MultiClient Chat Server -4
// send to everyone
void sendToALL(char * buf, int nbytes) {
int j, ret;
for(j = 0; j <= fdmax; j++) {
if (FD_ISSET(j, &master))
// except the listener and ourselves
if (j != listener && j != crt)
if ( send(j, buf, nbytes, 0) == -1)
perror("send");
}
return;
}
MultiClient Chat Server -5
int main(int argc, char **argv) {
if (argc < 2 ) {
printf("Usage:\n%s <portno>\n",argv[0]);
exit(1);
}
int_port = atoi(argv[1]);
FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);
// get the listener
if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
// get rid of the "address already in use" error message
if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int) ) == -1) {
perror("setsockopt:");
exit(1);
}
MultiClient Chat Server -6
// bind
memset(&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(int_port);
if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
perror("bind:");
exit(1);
}
// listen
if (listen(listener, 10) == -1) {
perror("listen");
exit(1);
}
// add the listener to the master set
FD_SET(listener, &master);
// keep track of the biggest file descriptor
fdmax = listener; // so far, it's this one
MultiClient Chat Server -7
// main loop
for(;;) {
read_fds = master; // copy it – select
if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
// run through the existing connections looking for data to read
for(i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) { // we got one!!
crt = i;
if (i == listener) {
// handle new connections
addrlen = sizeof(remoteaddr);
if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr,(socklen_t*)& addrlen)) == -1) {
perror("accept");
}
MultiClient Chat Server -8
else {
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax) { // keep track of the maximum
fdmax = newfd;
}
printf("selectserver: new connection from %s on socket %d\n",
getIPAddress(newfd, false),newfd);
client_count++;
sprintf(buf,"Hi-you are client :[%d] (%s:%d) connected to server %s\nThere
are %d clients connected\n", newfd, getIPAddress(newfd,false), getPort(newfd, false),
getIPAddress(listener, true), client_count);
send(newfd,buf,strlen(buf)+1,0);
}
}
MultiClient Chat Server -9
else {
// handle data from a client
if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
// got error or connection closed by client
if (nbytes == 0) {
// connection closed
printf("<selectserver>: client %d forcibly hung up\n", i);
}
else perror("recv");
client_count--;
close(i); // bye!
FD_CLR(i, &master); // remove from master set
}
else {
// we got some data from a client - check for connection close request
buf[nbytes]=0;
if ( (strncasecmp("QUIT\n",buf,4) == 0)) {
sprintf(buf,"Request granted [%d] - %s. Disconnecting...\n",i,getIPAddress(i,false));
MultiClient Chat Server -10
send(i,buf, strlen(buf)+1,0);
nbytes = sprintf(tmpbuf,"<%s - [%d]> disconnected\n",getIPAddress(i,false), i);
sendToALL(tmpbuf,nbytes);
client_count--;
close(i);
FD_CLR(i,&master);
}
else {
nbytes = sprintf(tmpbuf, "<%s - [%d]> %s",getIPAddress(crt, false),crt, buf);
sendToALL(tmpbuf, nbytes);
}
}
}
}
}
}
return 0;
}
MultiClient Chat Client -1
….//include stuff
…..
fd_set read_fds,master; // temp file descriptor list for select()
int sock; //socket
struct sockaddr_in servaddr;
char buf[256]; // buffer for client data
int nbytes, ret, int_port;

int main(int argc, char **argv)


{
if (argc < 3 ) {
printf("Usage:\n%s <hostname or IP address> <portno>\n",argv[0]);
exit(1);
}
MultiClient Chat Client -2
int_port = atoi(argv[2]);
int ipaddr = inet_addr(argv[1]);

// check if address is a hostname


if (ipaddr == -1 ) {
struct in_addr inaddr;
struct hostent * host = gethostbyname( argv[1] );
if (host == NULL ) {
printf("Error getting the host address\n");
exit(1);
}
memcpy(&inaddr.s_addr, host->h_addr_list[0],sizeof(inaddr));
printf("Connecting to %s ...\n",inet_ntoa( inaddr) );
memcpy(&ipaddr, host->h_addr_list[0],sizeof(unsigned long int)) ;
}
// create the socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
MultiClient Chat Client -3
memset(&servaddr,0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = ipaddr;
servaddr.sin_port = htons( int_port );
// connect to server
if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) {
perror("connect");
exit(1);
}
// add the socket to the master set
FD_ZERO(&read_fds); // clear the set
FD_ZERO(&master);
FD_SET(0, &master); FD_SET(sock, &master);
while(1) {
read_fds = master;
if (select(sock+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(1);
}
MultiClient Chat Client -4
if ( FD_ISSET(0, &read_fds) ) { // check if read from keyboard
nbytes = read(0, buf,sizeof(buf)-1);
ret = send(sock, buf, nbytes,0);
if (ret <= 0 ){
perror("send");
exit(1);
}
}
if ( FD_ISSET(sock, &read_fds) ) { // check if read from server
nbytes = read(sock, buf, sizeof(buf)-1);
if (nbytes <= 0) {
printf("Server has closed connection... closing...\n");
exit(2);
}
write(1,buf, nbytes);
}
}
return 0;
}
The OSI Reference Model

All People Seem To Need Data Processing


Principles of the OSI model
1. A layer should be created where a different
abstraction is needed.
2. Each layer should perform a well-defined function.
3. The function of each layer should be chosen with
an eye toward defining internationally standardized
protocols.
4. The layer boundaries should be chosen to minimize
the information flow across the interfaces.
5. The number of layers should be large enough that
distinct functions need not be thrown together in
the same layer out of necessity and small enough
that the architecture does not become unwieldy.
The Physical Layer
Raw bits over a communication channel
Data representation
 1–how many volts ?; 0 – how many volts ?
1 bit – How many nanoseconds ?
Bidirectional simultaneous transmission?
Electrical, mechanical, timing interfaces
Data Link layer
Turn the raw transmission into an error
free communication line
Sets data in frames=thousands of bytes
Traffic regulation (flow control)
Access to the medium in broadcast
shared communication lines
The Network Layer
Controls the operation of a subnet
How packets are routed from source to
destination
Quality of service – congestion control
Fragmentation and inter-network
problems
The Transport Layer
Accept data from upper layers and splits
it into packets (small units)
Ensure that packets arrive correctly to
the other end
Type of service: error free PtoP,
preserve order or not, guarantees
delivery or not, broadcast
True end-to-end layer
The Session Layer
Allows for establishing sessions
Session
 Dialog control
 Token management
 Synchronization
The Presentation Layer
Syntax and semantics of data
Abstract data definitions/ encoding for
information exchange between
heterogeneous systems
Standard encoding “on the wire”
Exchange unit – record type
The Application Layer
Protocols needed by users:
 HTTP - www
 FTP – file exchange
 TELNET – remote command
 SSH – remote command
 SMTP – mail exchange

You might also like