Beruflich Dokumente
Kultur Dokumente
광운대학교 컴퓨터과학과
정보통신 연구실
석사과정 안중현
4.1 Introduction
A Time line of the typical scenario
that takes place between a TCP client
and server.
Describes the elementary socket
functions required to write a complete
TCP client and server.
In this chapter, we consider only the
one-process-per-client model using
fork.
2
TCP Server
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
3 close ()
4.2 socket Function (1/4) socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
4 close ()
5
4.2 socket Function (3/4)
int socket (int family, int type, int protocol);
Protocol Description
IPPROTO_TCP TCP transport protocol
IPPROTO_UDP UDP transport protocol
IPPROTO_SCTP SCTP transport protocol
6
4.2 socket Function (4/4)
AF_xxx vs PF_xxx
AF_ : address family
used in socket address structures
PF_ : protocol family
used to create the socket
We use only the AF_ constants in this
text.
7
4.3 connect Function (1/5)socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
8 close ()
4.3 connect Function (2/5)
used by a TCP client to establish a connection
with a TCP server
#include <sys/socket.h>
int connect (int sockfd, const struct sockaddr
*servaddr, socklen_t addrlen); return: 0 if OK, -1 on error
sockfd: a socket descriptor returned by the socket
function.
*sveraddr: a pointer to a socket address structure
struct sockaddr
{
unsigned short sa_family; //address family (ex:AF_INET)
char sa_data[14]; //Family-specific address information
}
addrlen: socket address structure size
9
4.3 connect Function (3/5)
In the case of a TCP socket, the connect
function initiates TCP’s three-way
handshake.
The function returns only when the
connection is established or an error
occurs. Several examples.
If the client TCP receives no response to its
SYN segment, ETIMEDOUT is returned.
4.4BSD sends one SYN when connect is called,
another 6 seconds later, and another 24 seconds
later. If no response is received after a total of 75
seconds, the error is returned.
10
4.3 connect Function (4/5)
If the server’s response to the client’s SYN is a
reset(RST), this indicates that no process is
waiting for connections on the server host at
the port specified. This is a hard error and the
error ECONNREFUSED is returned to the client
as soon as the RST is received.
RST is a type of TCP segment that is sent by TCP
when something is wrong.
Three conditions that generate an RST
When a SYN arrives for a port that has no listening
server
When TCP wants to abort an existing connection
When TCP receives a segment for a connection that
does not exist
11
4.3 connect Function (5/5)
If the client’s SYN elicits an ICMP “destination
unreachable” from some intermediate router
This is considered a soft error
The client kernel saves the message but keeps
sending SYNs with the same time between each SYN.
If no response is received after some fixed amount of
time, the saved ICMP error is returned to the process
as either EHOSTUNREACH or ENETUNREACH.
12
4.4 bind Function (1/2) socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
13 close ()
4.4 bind Function (2/2)
Assigns a local protocol address to a
socket.
int bind (int sockfd, const struct sockaddr
*myaddr, socklen_t addrlen); return: 0 if OK, -1 on error
*myaddr: a pointer to a protocol-specific address
With TCP, calling bind lets us specify a port number, an
IP address, both, or neither.
Servers bind their well-known port when the start.
A process can bind a specific IP address to its
socket.
The man page description of bind has said “bind
assigns a name to an unnamed socket”.
14
4.5 listen Function (1/4) socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
15 close ()
4.5 listen Function (2/4)
Listen is called only by a TCP server
and performs
Converts an unconnected socket into a
passive socket.
int listen( int sockfd, int backlog );
Returns: 0 if OK, -1 on error
backlog
specify the maximum number of connections
that the kernel should queue for this socket.
Normally called after both the socket
and bind functions.
16
4.5 listen Function (3/4)
To understand Backlog
The kernal maintains two queues:
18
4.6 accept Function (1/3) socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
19 close ()
4.6 accept Function (2/3)
called by the TCP server to return the next
completed connection from the front of the
completed connection queue.
If the completed connection queue is
empty, the process is put to sleep.
int accept (int sockfd, struct sockaddr *cliaddr,
socklen_t *addrlen); Return: non-negative descriptor if OK
cliaddr: used to return the protocol address of the
connected peer process (i,e., the client process).
20
4.6 accept Function (3/3)
#include "unp.h" for ( ; ; ) {
#include <time.h> len = sizeof(cliaddr);
int main(int argc, char **argv) connfd = Accept(listenfd, (SA *) &cliaddr
{ , &len);
int listenfd, connfd; printf("connection from %s, port %d\n“
socklen_t len; , Inet_ntop(AF_INET, &cliaddr.sin_addr
struct sockaddr_in servaddr, cliaddr; , buff, sizeof(buff))
char buff[MAXLINE]; , ntohs(cliaddr.sin_port));
time_t ticks;
ticks = time(NULL);
listenfd = Socket(AF_INET, SOCK_STREAM, 0); snprintf(buff, sizeof(buff), "%.24s\r\n“
bzero(&servaddr, sizeof(servaddr)); , ctime(&ticks));
servaddr.sin_family = AF_INET; Write(connfd, buff, strlen(buff));
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); Close(connfd);
}
/* daytime server */ }
servaddr.sin_port = htons(13);
21
4.7 fork and exec Functions (1/3)
The only way in Unix to create a new
process.
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, -1 on error
24
4.8 Concurrent Servers (1/5)
Handle multiple clients at the same time.
When a connection is established, accept
returns, the server calls fork, and then the
child process services the client and the
parent process waits for another
connection.
The parent closes the connected socket
since the child handles this new client.
25
4.8 Concurrent Servers (2/5)
pid_t pid;
int listenfd, connfd;
listenfd = Socket(. . .);
/* file in sockaddr_in{} with server’s well-known port */
Bind(listenfd, . . . );
Listen(listenfd, LISTENQ);
for ( ; ; ){
connfd = Accept(listenfd, . . . ); /* probably blocks */
if ( (pid = Fork()) ==0){
Close(listenfd); /* child closes listening socket */
doit(connfd); /* process the request */
Close(connfd); /* done with this client */
exit(0); /* child terminates*/
}
Close(connfd); /*parent closes connected socket */
}
//-- Outline for typical concurrent server
26
4.8 Concurrent Servers (3/5)
Status of client-server before call to accept
returns
27
4.8 Concurrent Servers (4/5)
Status of client-server after fork returns
28
4.8 Concurrent Servers (5/5)
Status of client-server after parent and child close
appropriate sockets
29
4.9 close Function (1/2) socket ()
Well-known
port
bind ()
listen ()
TCP Client
accept ()
socket ()
Blocks until connection
Connection establishment from client
connect ()
(TCP three-way handshake)
data (request)
write () read ()
Process request
data (reply)
write ()
read ()
end-of-file notification
close () read ()
30 close ()
4.9 close Function (2/2)
The normal Unix close function is used to
close a socket and terminate a TCP
connection.
#include <unistd.h>
int close(int sockfd); Returns: 0 if OK, -1 on error
31
4.10 getsockname and getpeername
Function (1/3)
getsockname
return the local protocol address.
getpeername
return the foreign protocol address.
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr
*localaddr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr
*peeraddr, socklen_t *addrlen);
32
4.10 getsockname and getpeername
Function (2/3)
Two functions are required for the
following reasons
After connect successfully returns in a TCP
client that does not call bind, getsockname
returns the local IP address and local port
number assigned to the connection by the
kernel.
After calling bind with a port number of 0,
getsockname returns the local port number that
was assigned.
getsockname can be called to obtain the
address family of a socket, as Figure 4.19
33
4.10 getsockname and getpeername
Function (3/3)
/* include sockfd_to_family */
#include "unp.h"
int
sockfd_to_family(int sockfd)
{
struct sockaddr_storage ss; // Since we don’t know what type of socket
// address structure to allocate
socklen_t len;
len = sizeof(ss);
if (getsockname(sockfd, (SA *) &ss, &len) < 0)
return(-1);
return(ss.ss_family);
}
Figure 4.19 Return the address family of a socket
34
4.11 Summary
All clients and servers begin with a
call to socket, returning a socket
descriptor
Client the call connect, while servers
call bind, listen, and accept.
Sockets are normally closed with the
standard close function.
Most TCP servers are concurrent,
with the server calling fork for every
client connection that it handles.
35