TCP Sockets - RMIT University
TCP Sockets - RMIT University
TCP Sockets - RMIT University
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