Download TCP/UDP Sockets

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts

Flow-based programming wikipedia, lookup

Logic programming wikipedia, lookup

Programming language wikipedia, lookup

Falcon (programming language) wikipedia, lookup

Subroutine wikipedia, lookup

Abstraction (computer science) wikipedia, lookup

Stream processing wikipedia, lookup

Functional programming wikipedia, lookup

Object-oriented programming wikipedia, lookup

C syntax wikipedia, lookup

Go (programming language) wikipedia, lookup

IBM TPNS wikipedia, lookup

C Sharp (programming language) wikipedia, lookup

Reactive programming wikipedia, lookup

Structured programming wikipedia, lookup

Transcript
Lecture 10 Overview
Network API
• Application Programming Interface
– Services that provide the interface between
application and protocol software
• often by the operating system
Application
Network API
Protocol A
CPE 401/601 Lecture 10 : Socket Programming
Protocol B
Protocol C
2
Network API wish list
• Generic Programming Interface
– Support multiple communication protocol suites
(families)
– Address (endpoint) representation independence
– Provide special services for Client and Server?
• Support for message oriented and connection
oriented communication
• Work with existing I/O services
– when this makes sense
• Operating System independence
CPE 401/601 Lecture 10 : Socket Programming
3
Socket
• A socket is an abstract representation of a
communication endpoint
• Sockets work with Unix I/O services just like
files, pipes & FIFOs
• Sockets needs to
– establishing a connection
– specifying communication endpoint addresses
CPE 401/601 Lecture 10 : Socket Programming
4
Creating a Socket
int socket(int family, int type,
int proto);
• family specifies the protocol family
– PF_INET for TCP/IP
• type specifies the type of service
– SOCK_STREAM, SOCK_DGRAM
• protocol specifies the specific protocol
– usually 0, which means the default
CPE 401/601 Lecture 10 : Socket Programming
5
socket()
• The socket() system call returns a socket
descriptor (small integer) or -1 on error
• socket() allocates resources needed for a
communication endpoint
– but it does not deal with endpoint addressing
CPE 401/601 Lecture 10 : Socket Programming
6
Specifying an Endpoint Address
• Sockets API is generic
• There must be a generic way to specify
endpoint addresses
• TCP/IP requires an IP address and a port
number for each endpoint address
• Other protocol suites (families) may use other
schemes
CPE 401/601 Lecture 10 : Socket Programming
7
sockaddr
sockaddr_in6
length
AF_INET6
port
sockaddr
sa_len
sa_family
sockaddr_in
length
AF_INET
port
addr
Flow-label
sa_data
addr
zero
Scope ID
variable
16 bytes
28 bytes
CPE 401/601 Lecture 10 : Socket Programming
8
struct sockaddr_in (IPv4)
Length of
struct sockaddr_in {
structure (16)
uint8_t
sin_len;
AF_INET
sa_family_t
sin_family;
in_port_t
sin_port;
16 bit
Port number
struct in_addr sin_addr;
char
sin_zero[8];
Make structure
};
16 bytes
struct in_addr {
in_addr_t
s_addr;
32 bit
IPv4 address
};
CPE 401/601 Lecture 10 : Socket Programming
9
struct sockaddr_in (IPv6)
struct sockaddr_in6 {
Length of
structure (28)
uint8_t
sin6_len;
AF_INET6
sa_family_t
sin6_family;
in_port_t
sin6_port;
Port number
uint32_t
sin6_flowinfo;
Flow label
struct in6_addr sin6_addr;
Scope of
uint32_t
sin6_scope_id;
address
};
struct in6_addr {
128 bit
uint8_t
s6_addr[16];
IPv6 address
10
CPE 401/601 Lecture 10 : Socket Programming
};
Network Byte Order
• All values stored in a sockaddr_in must be in
network byte order.
– sin_port a TCP/IP port number
– sin_addr an IP address
•
•
•
•
uint16_t
uint16_t
uint32_t
uint32_t
htons(uint16_t);
ntohs(uint_16_t);
htonl(uint32_t);
ntohl(uint32_t);
CPE 401/601 Lecture 10 : Socket Programming
11
TCP/IP Addresses
• We don’t need to deal with sockaddr
structures since we will only deal with a real
protocol family.
• We can use sockaddr_in structures
• BUT: The C functions that make up the sockets
API expect structures of type sockaddr
CPE 401/601 Lecture 10 : Socket Programming
12
Assigning an address to a socket
• The bind() system call is used to assign an
address to an existing socket.
int bind( int sockfd,
const struct sockaddr *myaddr,
int addrlen);
• You can give bind() a sockaddr_in structure:
int bind( mysock,
(struct sockaddr*) &myaddr,
sizeof(myaddr) );
CPE 401/601 Lecture 10 : Socket Programming
13
bind() Example
int mysock,err;
struct sockaddr_in myaddr;
mysock =
socket(PF_INET,SOCK_STREAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( portnum );
myaddr.sin_addr = htonl( ipaddress);
err=bind(mysock, (sockaddr *)
&myaddr, sizeof(myaddr));
CPE 401/601 Lecture 10 : Socket Programming
14
Port schmort - who cares ?
• Clients typically don’t care what port they are
assigned
• When you call bind you can tell it to assign
you any available port:
– myaddr.port = htons(0);
CPE 401/601 Lecture 10 : Socket Programming
15
What is my IP address ?
• How can you find out what your IP address is
so you can tell bind() ?
• There is no realistic way for you to know the
right IP address to give bind()
– what if the computer has multiple network
interfaces?
• specify the IP address as: INADDR_ANY, this
tells the OS to take care of things.
CPE 401/601 Lecture 10 : Socket Programming
16
IPv4 Address Conversion
int inet_aton(char *, struct in_addr *);
– Convert ASCII dotted-decimal IP address to
network byte ordered 32 bit value.
– Returns 1 on success, 0 on failure.
char *inet_ntoa(struct in_addr);
– Convert network byte ordered value to ASCII
dotted-decimal (a string).
CPE 401/601 Lecture 10 : Socket Programming
17
IPv4 & IPv6 Address Conversion
int inet_pton(int, const char*, void*);
– (family, string_ptr, address_ptr)
– Convert IP address string to network byte ordered
32 or 128 bit value
– 1 on success, -1 on failure, 0 on invalid input
char *inet_ntop(int, const void*, char*,
size_t);
– (family, address_ptr, string_ptr, length)
– Convert network byte ordered value to IP address
string
• x:x:x:x:x:x:x:x or x:x:x:x:x:x:a.b.c.d
CPE 401/601 Lecture 10 : Socket Programming
18
Other socket system calls
• General Use
– read()
– write()
– close()
• Connection-oriented (TCP)
– connect()
– listen()
– accept()
• Connectionless (UDP)
– send()
– recv()
CPE 401/601 Lecture 10 : Socket Programming
19
Lecture 11
TCP and UDP Sockets
CPE 401 / 601
Computer Network Systems
slides
modified
from
Dave
Hollinger
slides
are are
modified
from
Dave
Hollinger
TCP Sockets Programming
• Creating a passive mode (server) socket
• Establishing an application-level connection
• send/receive data
• Terminating a connection
CPE 401/601 Lecture 11 : TCP Socket Programming
21
TCP state diagram
Creating a TCP socket
int socket(int family,int type,int proto);
– family: AF_INET, AF_INET6, AF_LOCAL, …
– type: SOCK_STREAM, SOCK_DGRAM,
SOCK_SEQPACKET, SOCK_RAW
– protocol: IPPROTO_TCP, IPPROTO_UDP,
IPPROTO_SCTP
int sock;
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock<0) { /* ERROR */ }
CPE 401/601 Lecture 11 : TCP Socket Programming
23
Binding to well known address
int bind(int sockfd, const struct
sockaddr *myaddr, socklen_t addrlen);
int mysock;
struct sockaddr_in myaddr;
mysock = socket(PF_INET,SOCK_STREAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( 80 );
myaddr.sin_addr = htonl( INADDR_ANY );
bind(mysock, (sockaddr *) &myaddr,
sizeof(myaddr));
CPE 401/601 Lecture 11 : TCP Socket Programming
24
Establishing a passive mode TCP socket
• Passive mode:
– Address already determined
• Tell the kernel to accept incoming connection
requests directed at the socket address
– 3-way handshake
• Tell the kernel to queue incoming connections
for us
CPE 401/601 Lecture 11 : TCP Socket Programming
25
listen()
int listen(int sockfd, int backlog);
• sockfd is the TCP socket
– already bound to an address
• backlog is the number of incoming
connections the kernel should be able to keep
track of (queue for us)
– Sum of incomplete and completed queues
CPE 401/601 Lecture 11 : TCP Socket Programming
26
Accepting an incoming connection
• Once we call listen(), the O.S. will queue
incoming connections
– Handles the 3-way handshake
– Queues up multiple connections
• When our application is ready to handle a new
connection
– we need to ask the O.S. for the next connection
CPE 401/601 Lecture 11 : TCP Socket Programming
27
accept()
int accept( int sockfd,
struct sockaddr* cliaddr,
socklen_t *addrlen);
• sockfd is the passive mode TCP socket
– initiated by socket(), bind(), and listen()
• cliaddr is a pointer to allocated space
• addrlen is a value-result argument
– must be set to the size of cliaddr
– on return, will be set to be the number of used
bytes in cliaddr
CPE 401/601 Lecture 11 : TCP Socket Programming
28
accept() return value
• accept() returns a new socket descriptor
(small positive integer) or -1 on error
• After accept returns a new socket descriptor,
I/O can be done using the read() and write()
system calls
• read() and write() operate a little differently
on sockets!
– vs. file operation!
CPE 401/601 Lecture 11 : TCP Socket Programming
29
Terminating a TCP connection
int close(int sockfd);
• Either end of the connection can call the
close() system call
• What if there is data being sent?
• If the other end has closed the connection,
and there is no buffered data, reading from a
TCP socket returns 0 to indicate EOF.
CPE 401/601 Lecture 11 : TCP Socket Programming
30
Client Code
• TCP clients can call connect() which:
– takes care of establishing an endpoint address for
the client socket
– Attempts to establish a connection to the
specified server
• 3-way handshake
• no need to call bind first, the O.S. will take
care of assigning the local endpoint address
– TCP port number, IP address
CPE 401/601 Lecture 11 : TCP Socket Programming
31
connect()
int connect( int sockfd,
const struct sockaddr *server,
socklen_t addrlen);
• sockfd is an already created TCP socket
• server contains the address of the server
• connect() returns 0 if OK, -1 on error
– No response to SYN segment (3 trials)
– RST signal
– ICMP destination unreachable (3 trials)
CPE 401/601 Lecture 11 : TCP Socket Programming
32
Reading from a TCP socket
int read(int fd, char *buf, int max);
• By default read() will block until data is
available
• reading from a TCP socket may return less
than max bytes
– whatever is available
• You must be prepared to read data 1 byte at a
time!
CPE 401/601 Lecture 11 : TCP Socket Programming
33
Writing to a TCP socket
int write(int fd, char *buf, int num);
• write might not be able to write all num bytes
on a nonblocking socket
• readn(), writen() and readline() functions
CPE 401/601 Lecture 11 : TCP Socket Programming
34
Metaphor for Good Relationships
• To succeed in relationships*:
– you need to establish your own identity.
– you need to be open & accepting.
– you need to establish contacts.
– you need to take things as they come, not as you
expect them.
– you need to handle problems as they arise.
*Copyright Dr. Laura’s Network Programming Corp.
CPE 401/601 Lecture 11 : TCP Socket Programming
35
UDP Sockets
UDP Sockets Programming
• Creating UDP sockets
– Client
– Server
• Sending data
• Receiving data
• Connected Mode
CPE 401/601 Lecture 11: UDP Socket Programming
37
Creating a UDP socket
int socket(int family, int type, int
proto);
int sock;
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock<0) { /* ERROR */ }
CPE 401/601 Lecture 11: UDP Socket Programming
38
Binding to well known address
• typically done by server only
int mysock;
struct sockaddr_in myaddr;
Mysock=socket(PF_INET,SOCK_DGRAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(1234);
myaddr.sin_addr = htonl(INADDR_ANY);
bind(mysock, &myaddr,
sizeof(myaddr));
CPE 401/601 Lecture 11: UDP Socket Programming
39
Sending UDP Datagrams
ssize_t sendto( int sockfd,
void *buff,
size_t nbytes, int flags,
const struct sockaddr* to,
socklen_t addrlen);
•
•
•
•
sockfd is a UDP socket
buff is the address of the data (nbytes long)
to is the destination address
Return value is the number of bytes sent,
– or -1 on error.
CPE 401/601 Lecture 11: UDP Socket Programming
40
sendto()
• The return value of sendto() indicates how
much data was accepted by the O.S. for
sending as a datagram
– not how much data made it to the destination.
• There is no error condition that indicates that
the destination did not get the data!!!
• You can send 0 bytes of data!
CPE 401/601 Lecture 11: UDP Socket Programming
41
Receiving UDP Datagrams
ssize_t recvfrom( int sockfd,
void *buff,
size_t nbytes, int flags,
struct sockaddr* from,
socklen_t *fromaddrlen);
•
•
•
•
sockfd is a UDP socket
buff is the address of a buffer (nbytes long)
from is the address of a sockaddr
Return value is the number of bytes received
and put into buff, or -1 on error
CPE 401/601 Lecture 11: UDP Socket Programming
42
recvfrom()
• If buff is not large enough, any extra data is
lost forever...
• You can receive 0 bytes of data!
• The sockaddr at from is filled in with the
address of the sender
CPE 401/601 Lecture 11: UDP Socket Programming
43
More recvfrom()
• recvfrom doesn’t return until there is a
datagram available,
– unless you do something special
• You should set fromaddrlen before calling
• If from and fromaddrlen are NULL we don’t
find out who sent the data
CPE 401/601 Lecture 11: UDP Socket Programming
44
Typical UDP client code
• Create UDP socket
• Create sockaddr with address of server
• Call sendto(), sending request to the server
– No call to bind() is necessary!
• Possibly call recvfrom()
– if we need a reply
CPE 401/601 Lecture 11: UDP Socket Programming
45
Typical UDP Server code
• Create UDP socket and bind to well known
address
• Call recvfrom() to get a request, noting the
address of the client
• Process request and send reply back with
sendto()
CPE 401/601 Lecture 11: UDP Socket Programming
46
Typical UDP Communication
CPE 401/601 Lecture 11: UDP Socket Programming
47
UDP Echo Server
int mysock;
struct sockaddr_in myaddr, cliaddr;
char msgbuf[MAXLEN];
socklen_t clilen;
int msglen;
mysock = socket(PF_INET,SOCK_DGRAM,0);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons( S_PORT );
myaddr.sin_addr = htonl( INADDR_ANY );
bind(mysock, &myaddr, sizeof(myaddr));
while (1) {
clilen=sizeof(cliaddr);
msglen=recvfrom(mysock,msgbuf,MAXLEN,0,
cliaddr,&clilen);
sendto(mysock,msgbuf,msglen,0,cliaddr,clilen);
}
CPE 401/601 Lecture 11: UDP Socket Programming
48