socket programming in C
Download
Report
Transcript socket programming in C
Socket Programming in C
Slides Adapted on
Jörn Altmann‘s Slides
Questions that will be Addressed
What mechanisms are available for a
programmer who writes network applications?
How to write a network application that sends
packets between hosts (client and server)
across an IP network?
Answer: socket API
Client
CEN4500C
IP Network
Server
2
Socket Programming
Table of Contents
1. Network Application Programming Interface:
2.
3.
4.
5.
6.
CEN4500C
Sockets and Internet Sockets
Network Programming Tips
Client-Server Architecture
Example: Client Programming
Example: Server Programming
Network Programmer’s Mistakes
3
Layers of the IP Protocol Suite
Application Layer
Transport Layer
Network Layer
Link Layer
CEN4500C
e.g. ftp
e.g. TCP, UDP
e.g. IP
Ethernet
Application Layer
Transport Layer
Network Layer
Link Layer
4
Protocol Suite Location
Internet Protocol Layer
Application Layer
Transport Layer (TCP, UDP)
Location
Applications
(e.g. browser, game, ftp)
Application Programming
Interface (API)
(e.g. network API)
Operating System
(e.g. Unix)
Network Layer (IP)
Interface to the Network Card
Link Layer
CEN4500C
Network Card &
Device Driver
(e.g. Ethernet card)
5
Network API
Operating system provides Application Programming
Interface (API) for network application
API is defined by a set of function types, data
structures, and constants
Desirable characteristics of the network interface
Simple to use
Flexible
independent from any application
allows program to use all functionality of the network
Standardized
allows programmer to learn once, write anywhere
Application Programming Interface for networks is
called socket
CEN4500C
6
Sockets
Sockets provide mechanisms to communicate
between computers across a network
There are different kind of sockets
DARPA Internet addresses (Internet Sockets)
Unix interprocess communication (Unix Sockets)
CCITT X.25 addresses
and many others
Berkeley sockets is the most popular Internet Socket
CEN4500C
runs on Linux, FreeBSD, OS X, Windows
fed by the popularity of TCP/IP
7
Internet Sockets
Support stream and datagram packets (e.g. TCP, UDP, IP)
Is Similar to UNIX file I/O API (provides a file descriptor)
Based on C, single thread model
does not require multiple threads
CEN4500C
8
Types of Internet Sockets
Different types of sockets implement different
communication types (stream vs. datagram)
Type of socket: stream socket
connection-oriented
two way communication
reliable (error free), in order delivery
can use the Transmission Control Protocol (TCP)
e.g. telnet, ssh, http
Type of socket: datagram socket
connectionless, does not maintain an open
connection, each packet is independent
can use the User Datagram Protocol (UDP)
e.g. IP telephony
Other types exist: similar to the one above9
CEN4500C
Network Programming Tips
Byte Ordering
Naming
Addressing
CEN4500C
10
Byte Ordering of Integers
Different CPU architectures have different byte
ordering
memory
address A +1
memory
address A
Stored at little-endian computer
high-order byte
Integer representation (2 byte)
D3
F2
low-order byte
high-order byte
Stored at big-endian computer
CEN4500C
low-order byte
11
Byte Ordering Problem
Question: What would happen if two computers
with different integer byte ordering communicate?
Answer:
Nothing if they do not exchange integers!
But: If they exchange integers, they would get the
wrong order of bytes, therefore, the wrong value!
Example:
Message is: [Hello,1]
Message in Memory of
little-endian Computer
48 45 4C 4C 6F 01 00
CEN4500C
Message is: [Hello,256]
Message is sent
across Network
Message in Memory of
of big-endian Computer
48 45 4C 4C 6F 01 00
12
Byte Ordering Solution
There are two solutions if computers with different byte
ordering system want to communicate
They must know the kind of architecture of the sending
computer
(bad solution, it has not been implemented)
Introduction of a network byte order. The functions are:
uint16_t
uint32_t
uint16_t
uint32_t
htons(uint16_t
htonl(uint32_t
ntohs(uint16_t
ntohs(uint32_t
host16bitvalue)
host32bitvalue)
net16bitvalue)
net32bitvalue)
Note: use for all integers (short and long), which
are sent across the network
Including port numbers and IP addresses
CEN4500C
13
Network Programming Tips
Byte Ordering
Naming
Addressing
CEN4500C
14
Naming and Addressing
Host name
identifies a single host (see Domain Name System
slides)
variable length string (e.g. www.berkeley.edu)
is mapped to one or more IP addresses
IP Address
written as dotted octets (e.g. 10.0.0.1)
32 bits. Not a number! But often needs to be
converted to a 32-bit to use.
Port number
identifies a process on a host
16 bit number
CEN4500C
15
Client-Server Architecture
response
Client
Server
request
Client requests service from server
Server responds with sending service or
error message to client
CEN4500C
16
Simple Client-Server Example
response
Client
Server
request
socket()
connect()
send()
recv()
close()
CEN4500C
Connection
establishment
socket()
bind()
listen()
accept()
Data request
recv()
Data response
send()
End-of-file notification
recv()
close()
17
Example: Client Programming
Create stream socket (socket() )
Connect to server (connect() )
While still connected:
send message to server (send() )
receive (recv() ) data from server and
process it
Close TCP connection and Socket
(close())
CEN4500C
18
socket(): Initializing Socket
Getting the file descriptor
int chat_sock;
if ((chat_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
printf("Failed to create socket\n");
abort ();
}
1.parameter specifies protocol/address family
2.parameter specifies the socket type
Other possibilities: SOCK_DGRAM
3.parameter specifies the protocol.
0 means protocol is chosen by the OS.
CEN4500C
19
IP Address Data Structure
struct sockaddr_in {
short int
unsigned short int
struct in_addr
unsigned char
};
sin_family; // Address family
sin_port;
// Port number
sin_addr;
// Internet address
sin_zero[8];
struct in_addr {
unsigned long
};
s_addr;
// 4 bytes
Padding of sin_zeros: struct sockaddr_in
has same size as struct sockaddr
CEN4500C
20
connect(): Making TCP
Connection to Server
struct sockaddr_in sin;
struct hostent *host = gethostbyname (argv[1]);
unsigned int server_address = *(unsigned long *) host->h_addr_list[0];
unsigned short server_port = atoi (argv[2]);
memset (&sin, 0, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = server_address;
sin.sin_port = htons (server_port);
if (connect(chat_sock, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
perror("connect");
printf("Cannot connect to server\n");
abort();
}
CEN4500C
21
send(): Sending Packets
int send_packets(char *buffer, int buffer_len) {
sent_bytes = send(chat_sock, buffer, buffer_len, 0);
if (send_bytes < 0) {
perror (“send");
}
return 0;
}
Needs socket descriptor,
Buffer containing the message, and
Length of the message
Can also use write()
CEN4500C
22
Receiving Packets:
Separating Data in a Stream
Fixed length
record
Fixed length
record
A
0
receive
buffer
B
1
2
C
3
4
5
D
6
7
8
9
slide through
Use records (data structures) to
partition the data stream
CEN4500C
23
Receiving Packets
int receive_packets(char *buffer, int buffer_len, int *bytes_read)
{
int left = buffer_len - *bytes_read;
received = recv(chat_sock, buffer + *bytes_read, left, 0);
if (received < 0) {
buffer_len
buffer
perror (“recv");
}
if (received <= 0) {
return close_connection();
}
*bytes_read
*bytes_read += received;
while (*bytes_read > RECORD_LEN) {
process_packet(buffer, RECORD_LEN);
*bytes_read -= RECORD_LEN;
memmove(buffer, buffer + RECORD_LEN, *bytes_read);
}
return 0;
}
Can also use read()
CEN4500C
24
Server Programming: Simple
Create stream socket (socket() )
Bind port to socket (bind() )
Listen for new client (listen() )
While
CEN4500C
accept user connection and create a new
socket (accept() )
data arrives from client (recv() )
data has to be send to client (send() )
25
bind(): Assign IP and Port
struct sockaddr_in sin;
struct hostent *host = gethostbyname (argv[1]);
unsigned int server_address = *(unsigned long *) host->h_addr_list[0];
unsigned short server_port = atoi (argv[2]);
memset (&sin, 0, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = server_address;
sin.sin_port = htons (server_port);
if (bind(chat_sock, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
perror("bind");
printf("Cannot bind server application to network\n");
abort();
}
CEN4500C
26
bind():
bind() tells the OS to assign a local IP address
and local port number to the socket.
Many applications let the OS choose an IP
address.
Use wildcard INADDR_ANY as local address in this case.
At server, user process must call bind() to
assign a port
At client, bind() is not required since OS may
assign available port and IP address
The server will get the port number of the client through
the UDP/TCP packet header
Note: Each application is represented by a
server port number
CEN4500C
27
listen(): Wait for Connections
int listen(int sockfd, int backlog);
Puts socket in a listening state, willing to
handle incoming TCP connection request.
Backlog: number of TCP connections that can
be queued at the socket.
CEN4500C
28
Server Example
#define MYPORT 3490 // the port users will be connecting to
#define BACKLOG 10 // how many pending connections queue will hold
int main(void) {
int sockfd, new_fd; // listen on sockfd, new connection on new_fd
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int sin_size;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family = AF_INET;
// host byte order
my_addr.sin_port = htons(MYPORT);
// short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // auto. filled with local IP
memset(&(my_addr.sin_zero), '\0', 8);
// zero the rest of the struct
CEN4500C
29
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
while(1) {
// main accept() loop
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
perror("send");
close(new_fd);
}
return 0;
}
CEN4500C
30
Client Example
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 3490
#define MAXDATASIZE 100
// the port client will be connecting to
// max number of bytes we can get
// at once
int main(int argc, char *argv[]) {
int
sockfd, numbytes;
char buf[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
// server's address information
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
perror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
CEN4500C}
31
their_addr.sin_family = AF_INET;
// host byte order
their_addr.sin_port = htons(PORT);
// short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr); // already network byte order
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1){
perror("connect");
exit(1);
}
if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}
buf[numbytes] = '\0';
printf("Received: %s",buf);
close(sockfd);
return 0;
}
CEN4500C
32
I/O Blocking
socket();
bind() ;
listen();
while
accept();
recv() ;
send() ;
Simple server has blocking problem
CEN4500C
Suppose 5 connections accepted.
Suppose next accept() blocks.
Other connections cannot send and receive.
Cannot get keyboard input either.
33
select() :I/O Multiplexing
waits on multiple file descriptors and timeout
returns when any file descriptor
is ready to be read or
written or
indicate an error, or
timeout exceeded
advantages
simple
application does not consume CPU cycles while
waiting
disadvantages
CEN4500C
does not scale to large number of file descriptors
34
Example:
Server Programming
create stream socket (socket() )
Bind port to socket (bind() )
Listen for new client (listen() )
While
Wait for (select() )
(depending on which file descriptors are ready)
accept user connection and create a new socket
(accept() )
data arrives from client (recv() )
data has to be send to client (send() )
CEN4500C
35
Server: Alternative Ways
of Handling Many Clients
Forking a new process for each client:
fork()
But, creating new process is expensive.
Multithreaded implementation: have
one thread handling each client.
Thread is like a process but lightweighted.
CEN4500C
36
Network Programmer’s
Mistakes
byte ordering
separating records in streams
use of select()
misinterpreting the project specification
not knowing all available system calls
CEN4500C
37
There are more System Calls
Depends on communication type
Datagram sockets use recvfrom() and sendto()
for receiving and sending data
Closing connection: close(), shutdown()
Convenient functions (on UNIX)
CEN4500C
inet_aton, inet_ntoa
inet_pton, inet_ntop
38
Literature
short tutorial: Beej's Guide to Network
Programming
http://www.ecst.csuchico.edu/~beej/guide/net/
Unix Network Programming, volumes 1 and
2 by W. Richard Stevens. Published by
Prentice Hall; ISBNs for volumes 1 and 2:
013490012X, 0130810819.
Advanced Programming in the Unix
Environment by W. Richard Stevens.
Published by Addison Wesley. ISBN
0201563177.
man pages on a Unix computer
CEN4500C
39