labs intro1
TRANSCRIPT
-
8/3/2019 Labs Intro1
1/33
Network Programming in C
Networked Systems 3
Laboratory Sessions and Problem Sets
-
8/3/2019 Labs Intro1
2/33
Lab Timetable, Aims, and Objectives
2
Teaching Week Activity
14 Introduction
15 Warm-up exercise
16
17 Web client
18
19
20
21
22
23 -
Aims and objectives To demonstrate how the world-wide
web works, at a protocol level
To teach concurrent networkprogramming in C
-
8/3/2019 Labs Intro1
3/33
Relation Between Labs and Lectures
3
1814 15 16 17 19 20 21 22 23Week
Layer
1
2
3
4
5
6
7 Lab
Lecture
-
8/3/2019 Labs Intro1
4/33
Network Programming in C:The Berkeley Sockets API
4
-
8/3/2019 Labs Intro1
5/33
The Berkeley Sockets API
Widely used low-level C networking API First introduced in 4.3BSD Unix
Now available on most platforms: Linux, MacOS X, Windows, FreeBSD,Solaris, etc.
Largely compatible cross-platform
Recommended reading: Stevens, Fenner, and Rudoff, Unix Network Programming
volume 1: The Sockets Networking API, 3rd Edition,Addison-Wesley, 2003.
5
-
8/3/2019 Labs Intro1
6/33
Concepts
Network
Socket
Application Sockets provide a standardinterface between networkand application
Two types of socket: Stream provides a virtual circuit service Datagram delivers individual packets
Independent of network type:
Commonly used with TCP/IP and UDP/IP,but not specific to the Internet protocols Only discuss TCP/IP sockets today
6
-
8/3/2019 Labs Intro1
7/33
What is a TCP/IP Connection?
A reliable byte-stream connection between twocomputers Most commonly used in a client-server fashion:
The server listens on a well-knownport Theportis a 16-bit number used to distinguish servers
E.g. web server listens on port 80, email server on port 25
The client connects to that port Once connection is established, either side can write data into the
connection, where it becomes available for the other side to read
The Sockets API represents the connection using afile descriptor
7
-
8/3/2019 Labs Intro1
8/33
bind(fd, ..., ...)
Network
Client
int fd = socket(...)
Server
?
listen(fd, ...)
connfd = accept(fd, ...)
read(connfd, buffer, buflen)
write(connfd, data, datalen)
close(connfd)
connect(fd, ..., ...)
write(fd, data, datalen)
read(fd, buffer, buflen)
close(fd)
int fd = socket(...)
Socket
fd
Socket
fd connfd
?
TCP/IP Connection
8
-
8/3/2019 Labs Intro1
9/33
TCP/IP Connection
fd = socket();
connect(fd, );
write(fd, );
read(fd, );
close(fd, );
fd = socket();
bind(fd, );
listen(fd, );
connfd = accept(fd, );
read(connfd, );
write(connfd, );
read(connfd, );
close(connfd, );
TCP/IP connection established
Send request
Wait for response
TCP/IP connection shutdownEOF read
Block until connectionestablished
Specify well-knownport
Begin listening
Client
Server
9
-
8/3/2019 Labs Intro1
10/33
Creating a socket
#include
int fd;
...
fd = socket(family, type, protocol);
if (fd == -1) {
// Error: unable to create socket
...
}
...
AF_INET for IPv4
AF_INET6 for IPv6
SOCK_STREAM for TCP
SOCK_DGRAM for UDP
0 (not used for Internet sockets)
Create an unbound socket, not connected to network;can be used as either a client or a server
#include
#include
10
-
8/3/2019 Labs Intro1
11/33
Handling Errors
fd = socket(family, type, protocol);
if (fd == -1) {
switch (errno) {case EPROTONOSUPPORT :
// Protocol not supported
...
case EACCESS:
// Permission denied
...
case ...default:
// Other error...
...
}
The Unix man pages list
possible errors that canoccur for each function
E.g. do man 2 socketin a terminal, and read the
ERRORS section
11
Socket functions return -1 and set the global variableerrno on failure
-
8/3/2019 Labs Intro1
12/33
Binding a Server Socket
Bind a socket to a porton a network interface Needed to run servers on a
well-known port - with addrspecified as INADDR_ANY
Not generally used on clients,since typically dont carewhich port used
#include #include
...
if (bind(fd, addr, addrlen) == -1) {
// Error: unable to bind
...
}
...
12
-
8/3/2019 Labs Intro1
13/33
Listening for Connections
#include
#include
if (listen(fd, backlog) == -1) {
// Error
...}
...
Tell the socket to listen for new connections
The backlogis the maximum number of connections thesocket will queue up, each waiting to be accept()ed
13
-
8/3/2019 Labs Intro1
14/33
Connecting to a Server
#include
#include
if (connect(fd, addr, addrlen) == -1) {
// Error: unable to open connection
...}
...
Tries to open a connection to the serverTimes out after 75 seconds if no response
Pointer to a struct sockaddr
Size of the struct in bytes
14
-
8/3/2019 Labs Intro1
15/33
Specifying Addresses & Ports
Must specify the address and port when callingbind() orconnect() The address can be either IPv4 or IPv6 Could be modelled in C as a union, but the designers of the sockets API
chose to use a number of structs, and abuse casting instead
15
-
8/3/2019 Labs Intro1
16/33
struct sockaddr
Addresses specified viastruct sockaddr
Has a data field big enough tohold the largest address of anyfamily
Plus sa_len and sa_familyto specify the length and typeof the address
Treats the address as an opaquebinary string
16
struct sockaddr {uint8_t sa_len;
sa_family_t sa_family;
char sa_data[22];
};
-
8/3/2019 Labs Intro1
17/33
struct sockaddr_in
17
Two variations exist forIPv4 and IPv6
addresses Use struct sockaddr_in to
hold an IPv4 address
Has the same size and memorylayout as struct sockaddr,
but interprets the bits differently
to give structure to the address
struct in_addr {
in_addr_t s_addr;
};
struct sockaddr_in {uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_pad[16];
};
-
8/3/2019 Labs Intro1
18/33
struct sockaddr_in6
18
Two variations exist forIPv4 and IPv6
addresses Use struct sockaddr_in6
to hold an IPv6 address
Has the same size and memorylayout as struct sockaddr,
but interprets the bits differently
to give structure to the address
struct in6_addr {
uint8_t s6_addr[16];
};
struct sockaddr_in6 {uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
};
-
8/3/2019 Labs Intro1
19/33
Working with Addresses
Work with eitherstruct sockaddr_in orstruct sockaddr_in6
Cast it to a struct sockaddr before callingthe socket routines
struct sockaddr_in addr;
...
// Fill in addr here
...if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1) {
...
19
-
8/3/2019 Labs Intro1
20/33
Creating an Address: Manually (Client)
inet_pton() to convert address
htons() to convert port
#include
#include
#include
#include
struct sockaddr_in addr;
...
inet_pton(AF_INET, 130.209.240.1, &addr.sin_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { ...
20
-
8/3/2019 Labs Intro1
21/33
-
8/3/2019 Labs Intro1
22/33
Creating an Address: DNS
Prefer using DNS names to raw IP addresses Use getaddrinfo() to look-up name in DNS Returns a linked list ofstruct addrinfo values, representing
addresses of the host
struct addrinfo {
int ai_flags; // input flags
int ai_family; // AF_INET, AF_INET6, ...
int ai_socktype; // IPPROTO_TCP, IPPROTO_UDP
int ai_protocol; // SOCK_STREAM, SOCK_DRAM, ...
socklen_t ai_addrlen; // length of socket-address
struct sockaddr *ai_addr; // socket-address for socket
char *ai_canonname; // canonical name of hoststruct addrinfo *ai_next; // pointer to next in list
};
22
-
8/3/2019 Labs Intro1
23/33
Connecting via a DNS Query
struct addrinfo hints, *ai, *ai0;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((i = getaddrinfo(www.google.com, "80", &hints, &ai0)) != 0) {
printf("Unable to look up IP address: %s", gai_strerror(i));
...
}
for (ai = ai0; ai != NULL; ai = ai->ai_next) {
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (fd == -1) {
perror("Unable to create socket");
continue;
}
if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
perror("Unable to connect");close(fd);
continue;
}
...
}
23
-
8/3/2019 Labs Intro1
24/33
Accepting Connections
#include
#include
int connfd;
struct sockaddr_in cliaddr;
socklen_t cliaddrlen = sizeof(cliaddr);
...connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
if (connfd == -1) {
// Error
...
}
...
Accepts a connection, returns newfile descriptor for the
connection (connfd) and client address (cliaddr)
24
-
8/3/2019 Labs Intro1
25/33
Accepting Connections
A TCP/IP server may have multiple connectionsoutstanding Can accept() connections one at a time, handling each request in
series
Can accept() connections and start a new thread for each, allowing it toprocess several in parallel
Each call to accept() returns a new file descriptor
25
-
8/3/2019 Labs Intro1
26/33
Reading and Writing Data
#define BUFLEN 1500
...
ssize_t i;
ssize_t rcount;
char buf[BUFLEN];
...rcount = read(fd, buf, BUFLEN);
if (rcount == -1) {
// Error has occurred
...
}
...
for (i = 0; i < rcount; i++) {printf(%c, buf[i]);
}
Read up to BUFLEN bytes ofdata from connection; blocksuntil data available
Returns actual number of
bytes read, or-1 on error
Data is notnull terminated
26
-
8/3/2019 Labs Intro1
27/33
Reading and Writing Data
char data[] = Hello, world!;
int datalen = strlen(data);
...
if (write(fd, data, datalen) == -1) {
// Error has occurred
...}
...
Send data on a TCP/IP connection; blocks until all data
can be written
Returns actual number of bytes written, or-1 on error
27
-
8/3/2019 Labs Intro1
28/33
Reading and Writing Data
#include
#include
#include
int main()
{
char x[] = "Hello, world!";
char *y = malloc(14);
sprintf(y, "Hello, world!");
printf("x = %s\n", x);
printf("y = %s\n", y);
printf("sizeof(x) = %d\n", sizeof(x));
printf("sizeof(y) = %d\n", sizeof(y));
printf("strlen(x) = %d\n", strlen(x));
printf("strlen(y) = %d\n", strlen(y));
return 0;
}
What gets printed?
Why?
28
-
8/3/2019 Labs Intro1
29/33
Closing a Socket
#include
close(fd);
Close and destroy a socket
Close the file descriptor for each connection, then the filedescriptor for the underlying socket
29
-
8/3/2019 Labs Intro1
30/33
Programming Exercises
30
-
8/3/2019 Labs Intro1
31/33
Laboratory work is assessed, total weighting 20%
All students are required to attend Wednesday labs
Assessment
31
Exercise Date set Date due* Weighting
Warm-up 13 January26 January,
12:00pm4%
Web client 27 January16 February,
12:00pm6%
Web server 17 February12 March,12:00pm
10%
* Note: these are hard deadlines; late submissions will receive a mark of zero unlessaccompanied by a valid special circumstances form.
-
8/3/2019 Labs Intro1
32/33
Warm-up Exercise
32
Write two programs in C: hello_client andhello_server The server listens for, and accepts, a single TCP connection; it reads all
the data it can from that connection, and prints it to the screen; then itcloses the connection
The client connects to the server, sends the string Hello, world!, thencloses the connection
Details on the handout
-
8/3/2019 Labs Intro1
33/33
Questions?
33