22.07.2013 Views

TCP Sockets - RMIT University

TCP Sockets - RMIT University

TCP Sockets - RMIT University

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Lecture 2<br />

Dr Andrew Fry<br />

<strong>RMIT</strong> <strong>University</strong><br />

Network Programming<br />

COSC 1176/1179<br />

Lecture 2<br />

Introduction to Socket Programming:<br />

Client/Server Design with <strong>TCP</strong>/UDP<br />

© School of Computer Science and Information<br />

Technology Slide 1


Lecture 2<br />

Dr Andrew Fry<br />

Lecture Overview<br />

During this lecture, we will learn <strong>TCP</strong> sockets<br />

Introduction to sockets<br />

<strong>TCP</strong> sockets<br />

Various functions related sockets<br />

Simple Server Design with <strong>TCP</strong> sockets<br />

Simple Client Design with <strong>TCP</strong> sockets<br />

we will also learn UDP sockets<br />

Introduction UDP sockets<br />

Differences between <strong>TCP</strong> and UDP<br />

Applications of UDP<br />

Socket functions for Network programming using UDP<br />

Examples of Simple UDP Client and Server<br />

© School of Computer Science and Information<br />

Technology Slide 2


Lecture 2<br />

Dr Andrew Fry<br />

Types of data deliveries<br />

© School of Computer Science and Information<br />

Technology Slide 3


Lecture 2<br />

Dr Andrew Fry<br />

Client-server model and Process-Process<br />

Interaction<br />

Client-Server interaction<br />

is a process-to-process<br />

interaction.<br />

Server could be a<br />

webserver, a mailserver, a<br />

database server, ftp<br />

server, telent server, ssh<br />

server etc.<br />

© School of Computer Science and Information<br />

Technology Slide 4


Well known services use well known ports<br />

Lecture 2<br />

Dr Andrew Fry<br />

Services could be<br />

supported by <strong>TCP</strong> or<br />

UDP, or others.<br />

Well known<br />

services use well<br />

known port numbers<br />

to be well identified.<br />

Servers can also<br />

use short lived ports<br />

to support<br />

concurrency<br />

Clients use<br />

temporary ports.<br />

© School of Computer Science and Information<br />

Technology Slide 5


Lecture 2<br />

Dr Andrew Fry<br />

/etc/services<br />

Port numbers of some well known services.<br />

echo 7/tcp<br />

echo 7/udp<br />

systat 11/tcp users<br />

daytime 13/tcp<br />

daytime 13/udp<br />

netstat 15/tcp<br />

ftp-data 20/tcp<br />

ftp 21/tcp<br />

ssh 22/tcp # Secure Shell<br />

telnet 23/tcp<br />

smtp 25/tcp mail<br />

© School of Computer Science and Information<br />

Technology Slide 6


Lecture 2<br />

Dr Andrew Fry<br />

Port Numbers, IP & Socket Address<br />

The combination of ip addr and<br />

port number is called a socket<br />

address<br />

© School of Computer Science and Information<br />

Technology Slide 7


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server starts by getting ready to receive client<br />

connections…<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 8


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int socket(int family, int type, int protocol);<br />

/* Create socket for incoming connections */<br />

if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_<strong>TCP</strong>)) < 0)<br />

DieWithError("socket() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 9


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int bind(int sockfd, const struct sockaddr *myaddr,<br />

socklen_t addrlen);<br />

echoServAddr.sin_family = AF_INET; /* Internet address family */<br />

echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);/* Any incoming interface */<br />

echoServAddr.sin_port = htons(echoServPort); /* Local port */<br />

if (bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)<br />

DieWithError("bind() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 10


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int listen(int sockfd, int backlog);<br />

/* Mark the socket so it will listen for incoming connections */<br />

if (listen(servSock, MAXPENDING) < 0)<br />

DieWithError("listen() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 11


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int accept(int sockfd,<br />

struct sockaddr* cliaddr, int *addrlen);<br />

for (;;) /* Run forever */<br />

{<br />

clntLen = sizeof(echoClntAddr);<br />

if ((clntSock=accept(servSock,(struct sockaddr *)&echoClntAddr,&clntLen)) < 0)<br />

DieWithError("accept() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 12


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

Server is now blocked waiting for connection from a client<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Later, a client decides to talk to the server…<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 13


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

/* Create a reliable, stream socket using <strong>TCP</strong> */<br />

if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_<strong>TCP</strong>)) < 0)<br />

DieWithError("socket() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 14


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int connect(int sockfd, const struct sockaddr*<br />

servaddr, int addrlen);<br />

echoServAddr.sin_family = AF_INET; /* Internet address family */<br />

echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */<br />

echoServAddr.sin_port = htons(echoServPort); /* Server port */<br />

if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)<br />

DieWithError("connect() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 15


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

if ((clntSock=accept(servSock,(struct sockaddr<br />

*)&echoClntAddr,&clntLen)) < 0)<br />

DieWithError("accept() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 16


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int send(SOCKET sockfd,<br />

const char* buf, int buflen,int flags);<br />

echoStringLen = strlen(echoString); /* Determine input length */<br />

/* Send the string to the server */<br />

if (send(sock, echoString, echoStringLen, 0) != echoStringLen)<br />

DieWithError("send() sent a different number of bytes than<br />

expected");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 17


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

int recv(SOCKET sockfd,<br />

char* buf, int len,int flags);<br />

/* Receive message from client */<br />

if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)<br />

DieWithError("recv() failed");<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 18


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> Client/Server Interaction<br />

Client<br />

1. Create a <strong>TCP</strong> socket<br />

2. Establish connection<br />

3. Communicate<br />

4. Close the connection<br />

int close(int sockfd);<br />

close(sock); close(clntSocket)<br />

Server<br />

1. Create a <strong>TCP</strong> socket<br />

2. Bind socket to a port<br />

3. Set socket to listen<br />

4. Repeatedly:<br />

a. Accept new connection<br />

b. Communicate<br />

c. Close the connection<br />

© School of Computer Science and Information<br />

Technology Slide 19


Summary of Socket Calls For a <strong>TCP</strong> Client &<br />

Server<br />

socket()<br />

Lecture 2<br />

Dr Andrew Fry<br />

socket()<br />

connect()<br />

write()<br />

read()<br />

close()<br />

Three Way Handshake<br />

Response<br />

Request<br />

End-of-File Notification<br />

bind()<br />

listen()<br />

accept()<br />

read()<br />

write()<br />

read()<br />

close()<br />

© School of Computer Science and Information<br />

Technology Slide 20


Lecture 2<br />

Dr Andrew Fry<br />

socket()<br />

Creates an endpoint for communication<br />

int socket(int family, int type, int protocol);<br />

family : specifies the protocol/address family for the socket:<br />

Typically, AF_INET or AF_UNIX (AF_LOCAL)<br />

AF_INET6 (for IPv6), AF_X25 (X.25 Protocols), AF_ATMPVC (ATM Private<br />

Virtual Circuits), AF_PACKET (low level packet communications)<br />

AF_ROUTE (access to routing tables), AF_KEY (new, for encryption)<br />

There are more.<br />

type : specifies the type of socket:<br />

Typically, SOCK_STREAM (reliable, connection oriented bytestream); or<br />

SOCK_DGRAM (unreliable, connectionless datagrams)<br />

SOCK_RAW (access to raw network protocols), and there are more.<br />

protocol : which protocol to use within the family, most often set<br />

to 0 (default protocol)<br />

IPPROTO_<strong>TCP</strong> for SOCK_STREAM, or IPPROTO_UDP for SOCK_DGRAM<br />

Returns a ‘socket descriptor’ if successful, or<br />

-1/INVALID_SOCKET on failure<br />

© School of Computer Science and Information<br />

Technology Slide 21


Lecture 2<br />

Dr Andrew Fry<br />

bind()<br />

Assigns a local protocol address (name) to a socket<br />

int bind(int sockfd, const struct sockaddr<br />

*myaddr, socklen_t addrlen);<br />

sockfd : is socket descriptor from socket()<br />

myaddr : protocol-specific structure containing the local<br />

address information. It is a pointer to address struct with:<br />

port number and IP address<br />

if port is 0, then host will pick ephemeral port not usually for<br />

server (exception RPC port-map)<br />

IP address = INADDR_ANY, indicates we want to bind to all of our<br />

local host’s addresses.<br />

addrlen : the size of the structure pointed to by myaddr<br />

Returns 0 on success or -1/SOCKET_ERROR if it fails.<br />

© School of Computer Science and Information<br />

Technology Slide 22


Lecture 2<br />

Dr Andrew Fry<br />

Socket Address Structure<br />

struct in_addr {<br />

in_addr_t s_addr; /* 32-bit IPv4 addresses */<br />

};<br />

struct sockaddr_in {<br />

unit8_t sin_len; /* length of structure */<br />

sa_family_t sin_family; /* AF_INET */<br />

in_port_t sin_port; /* <strong>TCP</strong>/UDP Port num */<br />

struct in_addr sin_addr; /* IPv4 address (above) */<br />

char sin_zero[8]; /* unused */<br />

}<br />

Are also “generic” and “IPv6” socket structures<br />

© School of Computer Science and Information<br />

Technology Slide 23


Lecture 2<br />

Dr Andrew Fry<br />

listen()<br />

Makes a socket ‘listen’ for new connections<br />

int listen(int sockfd, int backlog);<br />

sockfd : sockfd is socket descriptor from socket()<br />

backlog : specifies the length of the queue of waiting<br />

connections that the kernel should maintain. backlog is<br />

maximum number of incomplete connections<br />

historically 5<br />

rarely above 15 on a even moderate Web server!<br />

Returns 0 on success or -1/SOCKET_ERROR on<br />

failure<br />

© School of Computer Science and Information<br />

Technology Slide 24


Lecture 2<br />

Dr Andrew Fry<br />

accept()<br />

Accepts new connections from a listening socket<br />

int accept(int sockfd,<br />

struct sockaddr* cliaddr, int *addrlen);<br />

sockfd : sockfd is socket descriptor from socket()<br />

cliaddr : protocol-specific structure containing the<br />

remote address information<br />

addrlen : a pointer to the size of the structure pointed<br />

to by cliaddr, altered to indicate the size used<br />

Returns a new socket descriptor on success or<br />

-1/INVALID_SOCKET on failure<br />

© School of Computer Science and Information<br />

Technology Slide 25


Lecture 2<br />

Dr Andrew Fry<br />

connect()<br />

Used by <strong>TCP</strong> clients to establish a connection to a ‘listening’<br />

socket<br />

int connect(int sockfd, const struct sockaddr*<br />

servaddr, int addrlen);<br />

sockfd : sockfd is socket descriptor from socket()<br />

servddr : protocol-specific structure containing the local<br />

address information. servaddr is a pointer to a structure with:<br />

port number and IP address<br />

addrlen : the size of the structure pointed to by servaddr<br />

client doesn’t need bind()<br />

OS will pick ephemeral port<br />

Returns 0 on success or -1/SOCKET_ERROR on failure<br />

© School of Computer Science and Information<br />

Technology Slide 26


Lecture 2<br />

Dr Andrew Fry<br />

read() and write()<br />

Used by Unix <strong>TCP</strong> clients to read and write on a socket<br />

descriptor<br />

ssize_t read(int sockfd,<br />

void *buf, size_t buflen);<br />

ssize_t write(int sockfd,<br />

void *buf, size_t len);<br />

sockfd : socket descriptor (would be normally be fd)<br />

buf : a buffer containing either data to write or space to read<br />

into<br />

buflen/len : the maximum number of bytes which may be read or<br />

the number of bytes to write<br />

Returns the number of bytes read/written or -1 on failure<br />

read() returns 0 to indicate end-of-file<br />

© School of Computer Science and Information<br />

Technology Slide 27


Lecture 2<br />

Dr Andrew Fry<br />

send() and recv()<br />

int send(SOCKET sockfd,<br />

const char* buf, int buflen,<br />

int flags);<br />

int recv(SOCKET sockfd,<br />

char* buf, int len,<br />

int flags);<br />

sockfd : socket descriptor<br />

buf : a buffer containing either data to write or space to<br />

read into<br />

buflen/len : the maximum number of bytes which may be<br />

read or the number of bytes to write<br />

flags : bitwise OR of several options<br />

© School of Computer Science and Information<br />

Technology Slide 28


Lecture 2<br />

Dr Andrew Fry<br />

close()<br />

Closes a connection & frees associated resources<br />

int close(int sockfd);<br />

sockfd: socket descriptor<br />

closes socket for reading/writing<br />

returns (doesn’t block)<br />

attempts to send any unsent data<br />

Returns 0 on success or -1/SOCKET_ERROR on<br />

failure<br />

© School of Computer Science and Information<br />

Technology Slide 29


#include <br />

Lecture 2<br />

Dr Andrew Fry<br />

Simpleserver.c – walk through code<br />

#include <br />

#include <br />

#include <br />

const char NPMESSAGE[] = "Welcome to Network Programming.This is a fun<br />

course!\n";<br />

int main(int argc, char *argv[]) {<br />

int simpleSocket = 0;<br />

int simplePort = 0;<br />

int returnStatus = 0;<br />

struct sockaddr_in simpleServer;<br />

if (2 != argc) {<br />

}<br />

fprintf(stderr, "Usage: %s \n", argv[0]);<br />

exit(1);<br />

/* retrieve the port number for listening */<br />

simplePort = atoi(argv[1]);<br />

Program<br />

setup and<br />

parameter<br />

parsing<br />

© School of Computer Science and Information<br />

Technology Slide 30


Simpleserver.c – walk through code contd<br />

simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_<strong>TCP</strong>);<br />

if (simpleSocket == -1) {<br />

}<br />

else {<br />

}<br />

fprintf(stderr, "Could not create a socket!\n");<br />

exit(1);<br />

Lecture 2<br />

Dr Andrew Fry<br />

fprintf(stderr, "Socket created!\n");<br />

bzero(&simpleServer, sizeof(simpleServer));<br />

simpleServer.sin_family = AF_INET;<br />

simpleServer.sin_addr.s_addr = htonl(INADDR_ANY);<br />

simpleServer.sin_port = htons(simplePort);<br />

returnStatus = bind(simpleSocket,(struct sockaddr *)&simpleServer,sizeof(simpleServer));<br />

if (returnStatus == 0) {<br />

} else {<br />

fprintf(stderr, "Bind completed!\n");<br />

fprintf(stderr, "Could not bind to address!\n");<br />

close(simpleSocket);<br />

exit(1);}<br />

Create a <strong>TCP</strong><br />

socket<br />

/* setup the address structure<br />

*/<br />

/* use INADDR_ANY to<br />

bind to all local addresses */<br />

/* bind<br />

to the<br />

address<br />

and port<br />

with our<br />

socket<br />

*/<br />

© School of Computer Science and Information<br />

Technology Slide 31


Simpleserver.c – walk through code contd<br />

Lecture 2<br />

Dr Andrew Fry<br />

returnStatus = listen(simpleSocket, 5);<br />

if (returnStatus == -1) {<br />

}<br />

fprintf(stderr, "Cannot listen on socket!\n");<br />

close(simpleSocket);<br />

exit(1);<br />

Informs<br />

the <strong>TCP</strong><br />

implementat<br />

ion to<br />

allown<br />

incoming<br />

connections<br />

from clients<br />

© School of Computer Science and Information<br />

Technology Slide 32


while (1)<br />

{<br />

Simpleserver.c – walk through code contd<br />

struct sockaddr_in clientName = { 0 };<br />

int simpleChildSocket = 0;<br />

int clientNameLength = sizeof(clientName);<br />

simpleChildSocket = accept(simpleSocket,(struct sockaddr *)&clientName, &clientNameLength);<br />

if (simpleChildSocket == -1) {<br />

}<br />

fprintf(stderr, "Cannot accept connections!\n");<br />

close(simpleSocket);<br />

exit(1);<br />

write(simpleChildSocket, NPMESSAGE, strlen(NPMESSAGE));<br />

}<br />

}<br />

close(simpleChildSocket);<br />

close(simpleSocket);<br />

return 0;<br />

Lecture 2<br />

Dr Andrew Fry<br />

Wait here at<br />

the accept()<br />

call until a<br />

connection<br />

request is<br />

received<br />

from a<br />

client. So<br />

the default<br />

behavior is<br />

blocking.<br />

write<br />

out<br />

messag<br />

e to<br />

the<br />

clinet<br />

© School of Computer Science and Information<br />

Technology Slide 33


#include <br />

#include <br />

#include <br />

#include <br />

int main(int argc, char *argv[]) {<br />

int simpleSocket = 0;<br />

int simplePort = 0;<br />

int returnStatus = 0;<br />

char buffer[256] = "";<br />

struct sockaddr_in simpleServer;<br />

if (3 != argc) {<br />

}<br />

Lecture 2<br />

Dr Andrew Fry<br />

Simpleclient.c<br />

fprintf(stderr, "Usage: %s \n", argv[0]);<br />

exit(1);<br />

This is pretty<br />

similar to<br />

simpleserver<br />

Simpleserver can<br />

be modified to<br />

create simpleclient<br />

Remove bind(),<br />

listen(),accept()<br />

functions from<br />

simpleserver<br />

Add connect()<br />

Modify use of<br />

read()<br />

© School of Computer Science and Information<br />

Technology Slide 34


* create a streaming socket */<br />

Lecture 2<br />

Dr Andrew Fry<br />

Simpleclient.c<br />

simpleSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_<strong>TCP</strong>);<br />

if (simpleSocket == -1) {<br />

}<br />

else {<br />

}<br />

fprintf(stderr, "Could not create a socket!\n");<br />

exit(1);<br />

fprintf(stderr, "Socket created!\n");<br />

/* retrieve the port number for connecting */<br />

simplePort = atoi(argv[2]);<br />

/* setup the address structure */<br />

/* use the IP address sent as an argument for the server address */<br />

bzero(&simpleServer, sizeof(simpleServer));<br />

simpleServer.sin_family = AF_INET;<br />

inet_addr(argv[1], &simpleServer.sin_addr.s_addr);<br />

simpleServer.sin_port = htons(simplePort);<br />

These are part of<br />

the newly added<br />

code<br />

© School of Computer Science and Information<br />

Technology Slide 35


Lecture 2<br />

Dr Andrew Fry<br />

Simpleclient.c<br />

/* connect to the address and port with our socket */<br />

returnStatus = connect(simpleSocket, (struct sockaddr *)&simpleServer, sizeof(simpleServer));<br />

if (returnStatus == 0) {<br />

} else {<br />

}<br />

fprintf(stderr, "Connect successful!\n");<br />

fprintf(stderr, "Could not connect to address!\n");<br />

close(simpleSocket);<br />

exit(1);<br />

/* get the message from the server */<br />

returnStatus = read(simpleSocket, buffer, sizeof(buffer));<br />

if ( returnStatus > 0 ) {<br />

printf("%d: %s", returnStatus, buffer);<br />

} else {<br />

}<br />

fprintf(stderr, "Return Status = %d \n", returnStatus);<br />

close(simpleSocket);<br />

return 0;}<br />

These are part of<br />

the newly added<br />

code<br />

With these simple<br />

modifications you<br />

now have converted<br />

simpleserver -><br />

simpleclient !<br />

© School of Computer Science and Information<br />

Technology Slide 36


Solaris :<br />

Lecture 2<br />

Dr Andrew Fry<br />

Compiling code<br />

Goanna% gcc simpleserver.c -o simpleserver -lsocket -lnsl<br />

Goanna% gcc simpleclient.c -o simpleclient -lsocket -lnsl<br />

Linux :<br />

mymachine% gcc simpleserver.c -o simpleserver<br />

mymachine% gcc simpleclient.c -o simpleclient<br />

Get code from NP course webpage!!!<br />

© School of Computer Science and Information<br />

Technology Slide 37


Lecture 2<br />

Dr Andrew Fry<br />

Types of data deliveries<br />

Services could be supported by <strong>TCP</strong> or UDP, or others. (We have<br />

already learnt about <strong>TCP</strong> sockets in the previous lecture)<br />

Transmission Control Protocol<br />

Connection oriented<br />

RFC 793<br />

User Datagram Protocol (UDP)<br />

Connectionless<br />

RFC 768<br />

© School of Computer Science and Information<br />

Technology Slide 38


Lecture 2<br />

Dr Andrew Fry<br />

The Transport Layer<br />

IP protocol made it possible to shift packets between<br />

computers on different networks<br />

IP offers only ‘best effort connectionless’ service<br />

performance of intervening networks is unknown<br />

To ensure reliable, sequenced delivery the people at each end<br />

wrote their own ‘Transport Layer’ software<br />

Concerned with providing (reasonably) reliable, cost effective<br />

data transport from the source to the destination<br />

as programmers, this is really what we want from a<br />

network<br />

therefore the most used Application Programming<br />

Interfaces (APIs) for network programming are<br />

interfaces to the Transport layer<br />

© School of Computer Science and Information<br />

Technology Slide 39


Lecture 2<br />

Dr Andrew Fry<br />

Transport Layer as a Concept<br />

Design goals:<br />

service should meet user’s requirements independent of<br />

the underlying Network layer services<br />

service should be efficient<br />

uniform scheme for addressing should allow addressing<br />

of individual access points for application layer<br />

The Transport layer can implement:<br />

error control<br />

sequencing<br />

flow control<br />

© School of Computer Science and Information<br />

Technology Slide 40


Lecture 2<br />

Dr Andrew Fry<br />

/etc/services – udp based services<br />

Port numbers of some well known services.<br />

echo 7/tcp<br />

echo 7/udp<br />

systat 11/tcp users<br />

daytime 13/tcp<br />

daytime 13/udp<br />

netstat 15/tcp<br />

ftp-data 20/tcp<br />

ftp 21/tcp<br />

ssh 22/tcp # Secure Shell<br />

telnet 23/tcp<br />

smtp 25/tcp mail<br />

Many services are<br />

UDP based<br />

© School of Computer Science and Information<br />

Technology Slide 41


Connection-Oriented vs Connectionless Services:<br />

basic concept<br />

Connection-oriented service is like the telephone<br />

service:<br />

establish an end-to-end connection (for which you need a<br />

destination address);<br />

communicate via that connection;<br />

terminate the connection.<br />

Connectionless service is like the postal service:<br />

attach a destination address to a message, and send that<br />

message;<br />

repeat as necessary<br />

Lecture 2<br />

Dr Andrew Fry<br />

© School of Computer Science and Information<br />

Technology Slide 42


Lecture 2<br />

Dr Andrew Fry<br />

Reliable vs Unreliable Services<br />

A reliable service never corrupts or loses any part<br />

of the communication<br />

often achieved with end-to-end acknowledgement<br />

An unreliable service offers no such guarantee<br />

often more efficient & less delay<br />

In the Internet world the most common<br />

combinations are:<br />

reliable, connection oriented service (<strong>TCP</strong>); and<br />

unreliable, connectionless service (UDP).<br />

© School of Computer Science and Information<br />

Technology Slide 43


Lecture 2<br />

Dr Andrew Fry<br />

Connection Establishment<br />

© School of Computer Science and Information<br />

Technology Slide 44


Lecture 2<br />

Dr Andrew Fry<br />

<strong>TCP</strong> format<br />

© School of Computer Science and Information<br />

Technology Slide 45


Lecture 2<br />

Dr Andrew Fry<br />

UDP Header<br />

Like <strong>TCP</strong>, UDP adds ‘ports’ to<br />

addresses<br />

full transport-layer address is<br />

specified by IP address, protocol, and<br />

port<br />

Note: <strong>TCP</strong> and UDP do not share ports.<br />

© School of Computer Science and Information<br />

Technology Slide 46


Three-step connection establishment<br />

(<strong>TCP</strong>)<br />

Connection establishment<br />

Lecture 2<br />

Dr Andrew Fry<br />

Three way handshake<br />

Between pairs of ports<br />

One port can connect to multiple<br />

destinations<br />

Reliable communication between pairs<br />

of processes<br />

Across variety of reliable and<br />

unreliable networks and internets<br />

© School of Computer Science and Information<br />

Technology Slide 47


Four-step connection termination (<strong>TCP</strong>)<br />

Lecture 2<br />

Dr Andrew Fry<br />

© School of Computer Science and Information<br />

Technology Slide 48


Lecture 2<br />

Dr Andrew Fry<br />

User Datagram Protocol<br />

UDP offers a simple, unreliable connectionless service<br />

no concept of a connection<br />

no end-to-end reliability management<br />

a user interface to IP datagrams<br />

UDP is a convenient transport-layer protocol for applications<br />

that provide flow and error control. It is also used by<br />

multimedia applications<br />

Characteristics: Reduced overhead, Segments may get lost, Segments<br />

may arrive out of order<br />

Complexities<br />

Ordered Delivery,Retransmission strategy<br />

Duplication detection, Flow control<br />

Connection establishment, Connection termination<br />

Crash recovery<br />

© School of Computer Science and Information<br />

Technology Slide 49


Lecture 2<br />

Dr Andrew Fry<br />

When to Use (and not use)UDP<br />

Particularly appropriate circumstances include:<br />

broadcast applications<br />

multicast applications<br />

simple request-reply operations<br />

idempotent operations<br />

simple one way message transfer<br />

Particularly inappropriate circumstances include:<br />

error free bulk transfer<br />

© School of Computer Science and Information<br />

Technology Slide 50


Lecture 2<br />

Dr Andrew Fry<br />

When to Use <strong>TCP</strong><br />

<strong>TCP</strong> is a powerful and efficient error and flow<br />

control protocol<br />

Not appropriate for real-time streaming<br />

Not appropriate where the overhead of<br />

establishing and maintaining a connection is large<br />

compared to the load of the application itself<br />

Appropriate for specific applications in specific<br />

networks<br />

© School of Computer Science and Information<br />

Technology Slide 51


Summary of Socket Calls For a <strong>TCP</strong> Client &<br />

Server<br />

Operations for client-server connections:<br />

server must listen for connections<br />

client must connect to the server<br />

server must accept the connection<br />

client & server must send & receive data<br />

client & server must be able to disconnect<br />

Lecture 2<br />

Dr Andrew Fry<br />

socket()<br />

connect()<br />

write()<br />

read()<br />

close()<br />

Three Way Handshake<br />

Response<br />

Request<br />

End-of-File Notification<br />

socket()<br />

bind()<br />

listen()<br />

accept()<br />

read()<br />

write()<br />

read()<br />

close()<br />

© School of Computer Science and Information<br />

Technology Slide 52


Lecture 2<br />

Dr Andrew Fry<br />

Socket Calls For a UDP Client & Server<br />

Can use read(), write() and send(),<br />

recv() in connected mode UDP.<br />

Sendto()<br />

And<br />

Recvfrom()<br />

socket()<br />

connect()<br />

write()<br />

read()<br />

close()<br />

Three Way Handshake<br />

Response<br />

Request<br />

End-of-File Notification<br />

socket()<br />

bind()<br />

listen()<br />

accept()<br />

read()<br />

write()<br />

read()<br />

close()<br />

Recvfrom()<br />

And<br />

Sendto()<br />

© School of Computer Science and Information<br />

Technology Slide 53


Socket Calls For a UDP Client & Server<br />

Typical Socket Calls For a connectionless UDP Client & Server<br />

Lecture 2<br />

Dr Andrew Fry<br />

socket()<br />

sendto()<br />

recvfrom()<br />

close()<br />

Response<br />

Request<br />

socket()<br />

bind()<br />

recvfrom()<br />

sendto()<br />

© School of Computer Science and Information<br />

Technology Slide 54


Lecture 2<br />

Dr Andrew Fry<br />

Sending UDP Datagrams<br />

ssize_t sendto( int sockfd,<br />

sockfd is a UDP socket<br />

void *buff,<br />

size_t nbytes,<br />

int flags,<br />

const struct sockaddr* to,<br />

socklen_t addrlen);<br />

buff is the address of the data (nbytes long)<br />

(pointer to a buffer containing data to be transmitted)<br />

to is the address of a sockaddr containing the destination<br />

address.<br />

flags : covered in future lectures<br />

Return value is the number of bytes sent, or -1 on error.<br />

© School of Computer Science and Information<br />

Technology Slide 55


Lecture 2<br />

Dr Andrew Fry<br />

sendto()<br />

You can send 0 bytes of data! (Q: what does it<br />

mean?)<br />

The return value of sendto() indicates how much<br />

data was accepted by the O.S. for sending as a<br />

datagram - not how much data made it to the<br />

destination.<br />

There is no error condition that indicates that the<br />

destination did not get the data!!!<br />

Some possible errors :<br />

EBADF, ENOTSOCK: bad socket descriptor<br />

EFAULT: bad buffer address<br />

EMSGSIZE: message too large<br />

ENOBUFS: system buffers are full<br />

© School of Computer Science and Information<br />

Technology Slide 56


Lecture 2<br />

Dr Andrew Fry<br />

Receiving UDP Datagrams<br />

ssize_t recvfrom( int sockfd,<br />

void *buff,<br />

size_t nbytes,<br />

int flags,<br />

struct sockaddr* from,<br />

socklen_t *fromaddrlen);<br />

sockfd is a UDP socket<br />

buff is the address of a buffer (nbytes long)<br />

(pointer to a buffer that is used to store the received data)<br />

from is the address of a sockaddr.<br />

Return value is the number of bytes received<br />

and put into buff, or -1 on error.<br />

© School of Computer Science and Information<br />

Technology Slide 57


Lecture 2<br />

Dr Andrew Fry<br />

recvfrom()<br />

If buff is not large enough, any extra data is lost forever...<br />

You can receive 0 bytes of data! (Q: what does it mean?)<br />

The sockaddr at from is filled in with the address of the<br />

sender.<br />

You should set fromaddrlen before calling.<br />

If from and fromaddrlen are NULL we don’t find out who<br />

sent the data.<br />

Same errors as sendto, but also:<br />

EINTR: System call interrupted by signal.<br />

Unless you do something special - recvfrom doesn’t return<br />

until there is a datagram available.<br />

© School of Computer Science and Information<br />

Technology Slide 58


Lecture 2<br />

Dr Andrew Fry<br />

Typical UDP client code<br />

Create UDP socket.<br />

Create sockaddr with address of server.<br />

Call sendto(), sending request to the server. No<br />

call to bind() is necessary! (but you can use it)<br />

Possibly call recvfrom() (if we need a reply).<br />

int socket(int family,int type,int proto);<br />

int sock;<br />

sock = socket( PF_INET,<br />

SOCK_DGRAM,<br />

if (sock


Lecture 2<br />

Dr Andrew Fry<br />

Socket Address Structure revisited<br />

sockaddr with address of server (and client)<br />

struct in_addr {<br />

in_addr_t s_addr; /* 32-bit IPv4 addresses */<br />

};<br />

struct sockaddr_in {<br />

unit8_t sin_len; /* length of structure */<br />

sa_family_t sin_family; /* AF_INET */<br />

in_port_t sin_port; /* <strong>TCP</strong>/UDP Port num */<br />

struct in_addr sin_addr; /* IPv4 address (above) */<br />

char sin_zero[8]; /* unused */<br />

}<br />

Are also “generic” and “IPv6” socket structures<br />

© School of Computer Science and Information<br />

Technology Slide 60


Lecture 2<br />

Dr Andrew Fry<br />

Typical UDP Server code<br />

Create UDP socket and bind to well known address.<br />

Call recvfrom() to get a request, noting the<br />

address of the client.<br />

Process request and send reply back with<br />

sendto().<br />

int mysock;<br />

struct sockaddr_in myaddr;<br />

mysock = socket(PF_INET,SOCK_DGRAM,0);<br />

myaddr.sin_family = AF_INET;<br />

myaddr.sin_port = htons( 1234 );<br />

myaddr.sin_addr = htonl( INADDR_ANY );<br />

bind(mysock, &myaddr, sizeof(myaddr));<br />

© School of Computer Science and Information<br />

Technology Slide 61


* UDP Server */<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#define MAXBUF 1024<br />

int main(int argc, char* argv[])<br />

{<br />

int udpSocket;<br />

int returnStatus = 0;<br />

int addrlen = 0;<br />

struct sockaddr_in udpServer, udpClient;<br />

char buf[MAXBUF];<br />

Lecture 2<br />

Dr Andrew Fry<br />

A simple UDP Server<br />

if (argc < 2)<br />

{<br />

fprintf(stderr, "Usage: %s \n", argv[0]);<br />

exit(1);<br />

}<br />

/* initializing */<br />

/* check for the right number of<br />

arguments */<br />

udpSocket = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */<br />

© School of Computer Science and Information<br />

Technology Slide 62


if (udpSocket == -1)<br />

{<br />

}<br />

else {<br />

udpServer.sin_family = AF_INET;<br />

returnStatus = bind(udpSocket, (struct<br />

sockaddr*)&udpServer, sizeof(udpServer));<br />

if (returnStatus == 0) {<br />

}<br />

else {<br />

}<br />

Lecture 2<br />

Dr Andrew Fry<br />

fprintf(stderr, "Bind completed!\n");<br />

A simple UDP Server<br />

fprintf(stderr, "Could not create a socket!\n");<br />

exit(1);<br />

printf("Socket created.\n");}<br />

udpServer.sin_addr.s_addr = htonl(INADDR_ANY);<br />

udpServer.sin_port = htons(atoi(argv[1]));<br />

fprintf(stderr, "Could not bind to address!\n");<br />

close(udpSocket);<br />

exit(1);<br />

/* setup the server address and<br />

port */<br />

/* use INADDR_ANY to bind to all<br />

local addresses */<br />

/* use the port pased as<br />

argument */<br />

/* bind to the socket */<br />

© School of Computer Science and Information<br />

Technology Slide 63


while (1)<br />

}<br />

{<br />

}<br />

addrlen = sizeof(udpClient);<br />

Lecture 2<br />

Dr Andrew Fry<br />

A simple UDP Server<br />

returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0,<br />

if (returnStatus == -1) {<br />

}<br />

else {<br />

}<br />

(struct sockaddr*)&udpClient, &addrlen);<br />

fprintf(stderr, "Could not receive message!\n");<br />

printf("Received: %s\n", buf);<br />

strcpy(buf, "OK");<br />

returnStatus = sendto(udpSocket, buf, strlen(buf)+1, 0,<br />

if (returnStatus == -1) {<br />

}<br />

(struct sockaddr*)&udpClient, sizeof(udpClient));<br />

fprintf(stderr, "Could not send confirmation!\n");<br />

else { printf("Confirmation sent.\n"); }<br />

close(udpSocket);<br />

return 0;<br />

/* receive data<br />

from client */<br />

/* a message was<br />

received so send a<br />

confirmation */<br />

/* send data to<br />

client */<br />

/*cleanup */<br />

© School of Computer Science and Information<br />

Technology Slide 64


* UDP client */<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#define MAXBUF 1024<br />

int main(int argc, char* argv[])<br />

{<br />

int udpSocket;<br />

int returnStatus;<br />

int addrlen;<br />

struct sockaddr_in udpClient, udpServer;<br />

char buf[MAXBUF];<br />

if (argc < 3)<br />

{<br />

Lecture 2<br />

Dr Andrew Fry<br />

A simple UDP Client<br />

fprintf(stderr, "Usage: %s \n",<br />

argv[0]);<br />

}<br />

exit(1);<br />

© School of Computer Science and Information<br />

Technology Slide 65


* create a socket */<br />

Lecture 2<br />

Dr Andrew Fry<br />

A simple UDP Client<br />

udpSocket = socket(AF_INET, SOCK_DGRAM, 0);<br />

if (udpSocket == -1)<br />

{<br />

}<br />

else {<br />

}<br />

fprintf(stderr, "Could not create a socket!\n");<br />

exit(1);<br />

printf("Socket created.\n");<br />

/* client address */<br />

/* use INADDR_ANY to use all local addresses */<br />

udpClient.sin_family = AF_INET;<br />

udpClient.sin_addr.s_addr = INADDR_ANY;<br />

udpClient.sin_port = 0;<br />

© School of Computer Science and Information<br />

Technology Slide 66


eturnStatus = bind(udpSocket, (struct<br />

sockaddr*)&udpClient, sizeof(udpClient));<br />

if (returnStatus == 0) {<br />

}<br />

else {<br />

Lecture 2<br />

Dr Andrew Fry<br />

fprintf(stderr, "Bind completed!\n");<br />

A simple UDP Client<br />

fprintf(stderr, "Could not bind to address!\n");<br />

close(udpSocket);<br />

exit(1);<br />

}<br />

/* setup the message to be sent to the server */<br />

strcpy(buf, "Hey ..... What's UP?\n");<br />

/* server address */<br />

/* use the command line arguments */<br />

udpServer.sin_family = AF_INET;<br />

udpServer.sin_addr.s_addr = inet_addr(argv[1]);<br />

udpServer.sin_port = htons(atoi(argv[2]));<br />

© School of Computer Science and Information<br />

Technology Slide 67


Lecture 2<br />

Dr Andrew Fry<br />

A simple UDP Client<br />

returnStatus = sendto(udpSocket, buf, strlen(buf)+1, 0,<br />

(struct sockaddr*)&udpServer, sizeof(udpServer));<br />

if (returnStatus == -1) {<br />

fprintf(stderr, "Could not send message!\n");<br />

}<br />

else {<br />

printf("Message sent.\n");<br />

/* message sent: look for confirmation */<br />

addrlen = sizeof(udpServer);<br />

returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0,<br />

(struct sockaddr*)&udpServer, &addrlen);<br />

if (returnStatus == -1) {<br />

fprintf(stderr, "Did not receive confirmation!\n");<br />

}<br />

else {<br />

buf[returnStatus] = 0;<br />

printf("Received: %s\n", buf);<br />

}<br />

}<br />

close(udpSocket);<br />

return 0;<br />

}<br />

© School of Computer Science and Information<br />

Technology Slide 68


Lecture 2<br />

Dr Andrew Fry<br />

Connected mode<br />

A UDP socket can be used in a call to connect().<br />

This simply tells the O.S. the address of the peer.<br />

No handshake is made to establish that the peer<br />

exists.<br />

does not do three way handshake, or connection<br />

“connect” a misnomer, here. Should be setpeername()<br />

No data of any kind is sent on the network as a<br />

result of calling connect() on a UDP socket.<br />

© School of Computer Science and Information<br />

Technology Slide 69


Lecture 2<br />

Dr Andrew Fry<br />

Connected UDP<br />

connect() with SOCK_DGRAM sockets:<br />

Sets the destination for all further sends, allowing use of<br />

write() instead of sendto()<br />

Sets the source of all further reads, allowing the use of<br />

read() instead of recvfrom()<br />

Once a UDP socket is connected:<br />

Can also use send() instead of sendto()<br />

Can also use recv() instead of recvfrom()<br />

Asynchronous errors will be returned to the process.<br />

OS Specific, some won’t do this!<br />

© School of Computer Science and Information<br />

Technology Slide 70


Lecture 2<br />

Dr Andrew Fry<br />

Asynchronous error<br />

What happens if a client sends data to a server<br />

that is not running?<br />

ICMP “port unreachable” error is generated by receiving<br />

host and sent to sending host.<br />

The ICMP error may reach the sending host after<br />

sendto() has already returned!<br />

The next call dealing with the socket could return the<br />

error.<br />

© School of Computer Science and Information<br />

Technology Slide 71


Lecture 2<br />

Dr Andrew Fry<br />

Back to UDP connect()<br />

Connect() is typically used with UDP when<br />

communication is with a single peer only.<br />

Many UDP clients use connect().<br />

Some servers (TFTP).<br />

It is possible to disconnect and connect the same<br />

socket to a new peer.<br />

© School of Computer Science and Information<br />

Technology Slide 72


Lecture 2<br />

Dr Andrew Fry<br />

Why use connected UDP?<br />

Send two datagrams<br />

unconnected:<br />

connect the socket<br />

output first dgram<br />

unconnect the<br />

socket<br />

connect the socket<br />

ouput second dgram<br />

unconnect the<br />

socket<br />

Send two datagrams<br />

connected:<br />

connect the socket<br />

output first dgram<br />

ouput second dgram<br />

© School of Computer Science and Information<br />

Technology Slide 73


Lecture 2<br />

Dr Andrew Fry<br />

Next Time<br />

More about Server and client Design with <strong>TCP</strong><br />

Missing links (e.g sockaddr_in : bzero, memset; hton*, ntoh*;<br />

intet_addr)<br />

Identification functions: gethostbyaddr(), gethostbyname()<br />

etc.<br />

More examples of socket related functions<br />

© School of Computer Science and Information<br />

Technology Slide 74

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!