Chapter4
Elementary TCP Socket
abstract
Socket function
connect function
bind function
listen function
accept function
fork and exec function
concurrent server
close function
getsockname and getpeername function
Socket function
#include <sys/socket.h>
int socket(int family, int type, int protocol);
returns:nonnegative descriptor if OK, -1 on error
==>Normaly the protocol argument to the socket function is set to 0 exept
for raw socket.
Connect function
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr,
socklen_t addrlen);
Returns:0 if OK, -1 on error
==>this function used by a TCP client
Connect function
Return error
ETIMEOUT : no response from server
RST : server process is not running
EHOSTUNREACH : clients SYN unreachable
from some intermediate router.
bind function
#include <sys/socket.h>
int bind (int sockfd, const struct sockaddr *myaddr,
socklen_t addrlen);
Returns: 0 if OK, -1 on error
==>this function assigns a local protocol address
to a socket.
listen function
#include <sys/socket.h>
int listen(int sockfd, int backlog);
Returns:0 if OK, -1 on error
==>This function is called only by a TCP server
backlog =>specify the maximum number of connections that the
kernel should queue for this socket.
If the queues are full when client SYN arrives, TCP server ignore the
SYN, it does not send RST.
Backlog argument to the listen function has historically
specified the maximum value for the sum of both queues
accept function
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *cliaddr,
socklen_t *addrlen);
Returns:nonnegative descriptor if OK, -1 on error
=> return the next completed connection from the
front of the completed connection
queue.
If queue is empty, the process is put to sleep.
#include
"unp.h"
#include
<time.h>
int main(int argc, char **argv)
{
int
socklen_t
struct sockaddr_in
char
time_t
listenfd, connfd;
len;
servaddr, cliaddr;
buff[MAXLINE];
ticks;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port
= htons(13);
/* daytime server */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; ) {
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
printf("connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}
==>DayTime server that print client IP address and port.
fork and exec function
#include <unistd.h>
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, -1 on error
#include <unistd.h>
int execl(const char *pathname, const char *arg(), /*(char *) 0*/);
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg());
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg());
int execvp(const char *filename, char *const argv[]);
All six return: -1 on error, no return on success
Concurrent server
pid_t pid
int listenfd, connfd;
listenfd = Socket(...);
//fill in sockaddr_in{} with servers well-known port
Bind(listenfd, LISTENQ);
for(;;){
connfd = Accept(listenfd, ...);
doit(connfd);
//process the request
Close();
//done with this client
exit(0);
//child terminate
} Close(connfd);
// parent close connected socket
}
Figure 4.13 Outline for typical concurrent server
Close function
#include <unistd.h>
int close(int sockfd);
returns:0 if OK, -1 on error
getsockname and getpeername
function
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *localaddr,
socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *peeraddr,
socklen_t *addrlen);
both return : 0 if OK, -1 on error
=>getsockname : return local address associated with a socket
getpeername : foreign protocol address associated with a socket
#include "unp.h"
int sockfd_to_family(int sockfd)
{
union {
struct sockaddr sa;
char
} un;
socklen_t
len;
data[MAXSOCKADDR];
len = MAXSOCKADDR;
if (getsockname(sockfd, (SA *) un.data, &len) < 0)
return(-1);
return(un.sa.sa_family);
}
Figure 4.19 Return the address family of a socket