#include "unp.h"
int tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
{
int listenfd, n;
const int on=1;
struct addrinfo hints, res, &ressave;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_flags=AI_PASSIVE;
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_STREAM;
if((n=getaddrinfo(host,serv,&hints, &res))!=0)
err_quit("tcp_listen error for %s, %s: %s", host ,serv, gai_strerror(n));
ressave=res;
do{
listenfd=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(listenfd<0)
continue;
Setsockopt(listenfd, SOL_SOCKET, SO_RESUSEADDR,&on, sizeof(on));
if(bind(listenfd, res->ai_addr, res->ai_addrlen)==0)
break;
Close(listenfd);
}while((res=res->ai_next)!=NULL);
if(res==NULL)
err_sys("tcp_listen error for %s, %s", host, serv);
Listen(listenfd, LISTENQ);
if(addrlenp)
*addrlenp=res->ai_addrlen;
freeaddrinfo(ressave);
return listenfd;
}
tcp_listen function: performs normal server steps
#include "unp.h"
#include <time.h>
int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
char buff[MAXLINE];
time_t ticks;
struct sockaddr_storage clientaddr;
if(argc!=2)
err_quit("usage: daytimetcpserv1 <service or port#>");
listenfd=Tcp_listen(NULL, argv[1], NULL);
for(;;)
{
len=sizeof(clientaddr);
connfd=Accept(listenfd, (SA *) &clientaddr, &len);
printf("connection from %s\n",Sock_ntop((SA *)&clientaddr, len));
ticks=time(NULL);
snprintf(buff, sizeof(buff),"%.24s\r\n",ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}
Daytime server recoded to use tcp_listen (see also Figure 11.14)