第20章 广播
20.4 使用广播的dg_cli函数
//运行前启动daytime服务,运行:./client 192.168.1.255,启动后,随便输入字符
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <strings.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <sys/un.h>
#define MAXLINE 4096 /* max text line length */
#define SA struct sockaddr
typedef void Sigfunc(int); /* for signal handlers */
void err_doit(int errnoflag, const char *fmt, va_list ap)
{
int errno_save;
char buf[MAXLINE];
errno_save = errno; /* value caller might want printed */
vsprintf(buf, fmt, ap);
if (errnoflag)
sprintf(buf + strlen(buf), ": %s", strerror(errno_save));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr); /* SunOS 4.1.* doesn't grok NULL argument */
return;
}
void err_quit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
exit(1);
}
void err_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
exit(1);
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
err_sys("socket error");
return (n);
}
void Inet_pton(int family, const char *strptr, void *addrptr)
{
int n;
if ((n = inet_pton(family, strptr, addrptr)) < 0)
err_sys("inet_pton error for %s", strptr); /* errno set */
else if (n == 0)
err_quit("inet_pton error for %s", strptr); /* errno not set */
/* nothing to return */
}
char *Fgets(char *ptr, int n, FILE * stream)
{
char *rptr;
if ((rptr = fgets(ptr, n, stream)) == NULL && ferror(stream))
err_sys("fgets error");
return (rptr);
}
ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr * sa, socklen_t * salenptr)
{
ssize_t n;
if ((n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
err_sys("recvfrom error");
return (n);
}
void Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen)
{
if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t) nbytes)
err_sys("sendto error");
}
void Fputs(const char *ptr, FILE * stream)
{
if (fputs(ptr, stream) == EOF)
err_sys("fputs error");
}
void recvfrom_alarm(int signo)
{
return; /* just interrupt the recvfrom() */
}
void *Malloc(size_t size)
{
void *ptr;
if ((ptr = malloc(size)) == NULL)
err_sys("malloc error");
return (ptr);
}
void Setsockopt(int fd, int level, int optname, const void *optval,
socklen_t optlen)
{
if (setsockopt(fd, level, optname, optval, optlen) < 0)
err_sys("setsockopt error");
}
Sigfunc *signal(int signo, Sigfunc * func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
#endif
}
if (sigaction(signo, &act, &oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
Sigfunc *Signal(int signo, Sigfunc * func)
{ /* for our signal() function */
Sigfunc *sigfunc;
if ((sigfunc = signal(signo, func)) == SIG_ERR)
err_sys("signal error");
return (sigfunc);
}
char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
static char str[128]; /* Unix domain is largest */
switch (sa->sa_family) {
case AF_INET:{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))
== NULL)
return (NULL);
return (str);
}
#ifdef IPV6
case AF_INET6:{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
if (inet_ntop
(AF_INET6, &sin6->sin6_addr, str,
sizeof(str)) == NULL)
return (NULL);
return (str);
}
#endif
#ifdef AF_UNIX
case AF_UNIX:{
struct sockaddr_un *unp = (struct sockaddr_un *)sa;
/* OK to have no pathname bound to the socket: happens on
every connect() unless client calls bind() first. */
if (unp->sun_path[0] == 0)
strcpy(str, "(no pathname bound)");
else
snprintf(str, sizeof(str), "%s", unp->sun_path);
return (str);
}
#endif
#ifdef HAVE_SOCKADDR_DL_STRUCT
case AF_LINK:{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
if (sdl->sdl_nlen > 0)
snprintf(str, sizeof(str), "%*s",
sdl->sdl_nlen, &sdl->sdl_data[0]);
else
snprintf(str, sizeof(str), "AF_LINK, index=%d",
sdl->sdl_index);
return (str);
}
#endif
default:
snprintf(str, sizeof(str),
"sock_ntop_host: unknown AF_xxx: %d, len %d",
sa->sa_family, salen);
return (str);
}
return (NULL);
}
char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
char *ptr;
if ((ptr = sock_ntop_host(sa, salen)) == NULL)
err_sys("sock_ntop_host error"); /* inet_ntop() sets errno */
return (ptr);
}
void dg_cli(FILE * fp, int sockfd, const SA * pservaddr, socklen_t servlen)
{
int n;
const int on = 1;
char sendline[MAXLINE], recvline[MAXLINE + 1];
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = (struct sockaddr *)Malloc(servlen);
Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
Signal(SIGALRM, recvfrom_alarm);
while (Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr,
servlen);
alarm(5);
for (;;) {
len = servlen;
n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr,
&len);
if (n < 0) {
if (errno == EINTR)
break; /* waited long enough for replies */
else
err_sys("recvfrom error");
} else {
recvline[n] = 0; /* null terminate */
printf("from %s: %s",
Sock_ntop_host(preply_addr, len),
recvline);
}
}
}
free(preply_addr);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: udpcli <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(stdin, sockfd, (SA *) & servaddr, sizeof(servaddr));
exit(0);
}
22.5 竞争条件
22.5.2 用pselect阻塞和解阻塞信号
//运行前启动daytime服务,运行:./client 192.168.1.255,启动后,随便输入字符
#define _POSIX_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <sys/select.h>
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <strings.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <sys/un.h>
#define MAXLINE 4096 /* max text line length */
#define SA struct sockaddr
typedef void Sigfunc(int); /* for signal handlers */
void err_doit(int errnoflag, const char *fmt, va_list ap)
{
int errno_save;
char buf[MAXLINE];
errno_save = errno; /* value caller might want printed */
vsprintf(buf, fmt, ap);
if (errnoflag)
sprintf(buf + strlen(buf), ": %s", strerror(errno_save));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr); /* SunOS 4.1.* doesn't grok NULL argument */
return;
}
void err_quit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
exit(1);
}
void err_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
exit(1);
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
err_sys("socket error");
return (n);
}
void Inet_pton(int family, const char *strptr, void *addrptr)
{
int n;
if ((n = inet_pton(family, strptr, addrptr)) < 0)
err_sys("inet_pton error for %s", strptr); /* errno set */
else if (n == 0)
err_quit("inet_pton error for %s", strptr); /* errno not set */
/* nothing to return */
}
char *Fgets(char *ptr, int n, FILE * stream)
{
char *rptr;
if ((rptr = fgets(ptr, n, stream)) == NULL && ferror(stream))
err_sys("fgets error");
return (rptr);
}
ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr * sa, socklen_t * salenptr)
{
ssize_t n;
if ((n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
err_sys("recvfrom error");
return (n);
}
void Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen)
{
if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t) nbytes)
err_sys("sendto error");
}
void Fputs(const char *ptr, FILE * stream)
{
if (fputs(ptr, stream) == EOF)
err_sys("fputs error");
}
void recvfrom_alarm(int signo)
{
return; /* just interrupt the recvfrom() */
}
void *Malloc(size_t size)
{
void *ptr;
if ((ptr = malloc(size)) == NULL)
err_sys("malloc error");
return (ptr);
}
void Setsockopt(int fd, int level, int optname, const void *optval,
socklen_t optlen)
{
if (setsockopt(fd, level, optname, optval, optlen) < 0)
err_sys("setsockopt error");
}
Sigfunc *signal(int signo, Sigfunc * func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
#endif
}
if (sigaction(signo, &act, &oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
Sigfunc *Signal(int signo, Sigfunc * func)
{ /* for our signal() function */
Sigfunc *sigfunc;
if ((sigfunc = signal(signo, func)) == SIG_ERR)
err_sys("signal error");
return (sigfunc);
}
char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
static char str[128]; /* Unix domain is largest */
switch (sa->sa_family) {
case AF_INET:{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))
== NULL)
return (NULL);
return (str);
}
#ifdef IPV6
case AF_INET6:{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
if (inet_ntop
(AF_INET6, &sin6->sin6_addr, str,
sizeof(str)) == NULL)
return (NULL);
return (str);
}
#endif
#ifdef AF_UNIX
case AF_UNIX:{
struct sockaddr_un *unp = (struct sockaddr_un *)sa;
/* OK to have no pathname bound to the socket: happens on
every connect() unless client calls bind() first. */
if (unp->sun_path[0] == 0)
strcpy(str, "(no pathname bound)");
else
snprintf(str, sizeof(str), "%s", unp->sun_path);
return (str);
}
#endif
#ifdef HAVE_SOCKADDR_DL_STRUCT
case AF_LINK:{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
if (sdl->sdl_nlen > 0)
snprintf(str, sizeof(str), "%*s",
sdl->sdl_nlen, &sdl->sdl_data[0]);
else
snprintf(str, sizeof(str), "AF_LINK, index=%d",
sdl->sdl_index);
return (str);
}
#endif
default:
snprintf(str, sizeof(str),
"sock_ntop_host: unknown AF_xxx: %d, len %d",
sa->sa_family, salen);
return (str);
}
return (NULL);
}
char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
char *ptr;
if ((ptr = sock_ntop_host(sa, salen)) == NULL)
err_sys("sock_ntop_host error"); /* inet_ntop() sets errno */
return (ptr);
}
void Sigemptyset(sigset_t * set)
{
if (sigemptyset(set) == -1)
err_sys("sigemptyset error");
}
void Sigaddset(sigset_t * set, int signo)
{
if (sigaddset(set, signo) == -1)
err_sys("sigaddset error");
}
void Sigprocmask(int how, const sigset_t *set, sigset_t *oset)
{
if (sigprocmask(how, set, oset) == -1)
err_sys("sigprocmask error");
}
void dg_cli(FILE * fp, int sockfd, const SA * pservaddr, socklen_t servlen)
{
int n;
const int on = 1;
char sendline[MAXLINE], recvline[MAXLINE + 1];
fd_set rset;
sigset_t sigset_alrm, sigset_empty;
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = Malloc(servlen);
Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
FD_ZERO(&rset);
Sigemptyset(&sigset_empty);
Sigemptyset(&sigset_alrm);
Sigaddset(&sigset_alrm, SIGALRM);
Signal(SIGALRM, recvfrom_alarm);
while (Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr,
servlen);
Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);
alarm(5);
for (;;) {
FD_SET(sockfd, &rset);
n = pselect(sockfd + 1, &rset, NULL, NULL, NULL,
&sigset_empty);
if (n < 0) {
if (errno == EINTR)
break;
else
err_sys("pselect error");
} else if (n != 1)
err_sys("pselect error: returned %d", n);
len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr,
&len);
recvline[n] = 0; /* null terminate */
printf("from %s: %s",
Sock_ntop_host(preply_addr, len), recvline);
}
}
free(preply_addr);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: udpcli <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(stdin, sockfd, (SA *) & servaddr, sizeof(servaddr));
exit(0);
}
22.5.4 使用信号处理函数到主控函数的IPC
//运行前启动daytime服务,运行:./client 192.168.1.255,启动后,随便输入字符
#define _POSIX_SOURCE
#include <sys/select.h>
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <strings.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <sys/un.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define MAXLINE 4096 /* max text line length */
#define SA struct sockaddr
typedef void Sigfunc(int); /* for signal handlers */
void err_doit(int errnoflag, const char *fmt, va_list ap)
{
int errno_save;
char buf[MAXLINE];
errno_save = errno; /* value caller might want printed */
vsprintf(buf, fmt, ap);
if (errnoflag)
sprintf(buf + strlen(buf), ": %s", strerror(errno_save));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr); /* SunOS 4.1.* doesn't grok NULL argument */
return;
}
void err_quit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
exit(1);
}
void err_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, fmt, ap);
va_end(ap);
exit(1);
}
int Socket(int family, int type, int protocol)
{
int n;
if ((n = socket(family, type, protocol)) < 0)
err_sys("socket error");
return (n);
}
void Inet_pton(int family, const char *strptr, void *addrptr)
{
int n;
if ((n = inet_pton(family, strptr, addrptr)) < 0)
err_sys("inet_pton error for %s", strptr); /* errno set */
else if (n == 0)
err_quit("inet_pton error for %s", strptr); /* errno not set */
/* nothing to return */
}
char *Fgets(char *ptr, int n, FILE * stream)
{
char *rptr;
if ((rptr = fgets(ptr, n, stream)) == NULL && ferror(stream))
err_sys("fgets error");
return (rptr);
}
ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
struct sockaddr * sa, socklen_t * salenptr)
{
ssize_t n;
if ((n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr)) < 0)
err_sys("recvfrom error");
return (n);
}
void Sendto(int fd, const void *ptr, size_t nbytes, int flags,
const struct sockaddr *sa, socklen_t salen)
{
if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t) nbytes)
err_sys("sendto error");
}
void Fputs(const char *ptr, FILE * stream)
{
if (fputs(ptr, stream) == EOF)
err_sys("fputs error");
}
void *Malloc(size_t size)
{
void *ptr;
if ((ptr = malloc(size)) == NULL)
err_sys("malloc error");
return (ptr);
}
void Setsockopt(int fd, int level, int optname, const void *optval,
socklen_t optlen)
{
if (setsockopt(fd, level, optname, optval, optlen) < 0)
err_sys("setsockopt error");
}
Sigfunc *signal(int signo, Sigfunc * func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */
#endif
}
if (sigaction(signo, &act, &oact) < 0)
return (SIG_ERR);
return (oact.sa_handler);
}
Sigfunc *Signal(int signo, Sigfunc * func)
{ /* for our signal() function */
Sigfunc *sigfunc;
if ((sigfunc = signal(signo, func)) == SIG_ERR)
err_sys("signal error");
return (sigfunc);
}
char *sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
static char str[128]; /* Unix domain is largest */
switch (sa->sa_family) {
case AF_INET:{
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str))
== NULL)
return (NULL);
return (str);
}
#ifdef IPV6
case AF_INET6:{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
if (inet_ntop
(AF_INET6, &sin6->sin6_addr, str,
sizeof(str)) == NULL)
return (NULL);
return (str);
}
#endif
#ifdef AF_UNIX
case AF_UNIX:{
struct sockaddr_un *unp = (struct sockaddr_un *)sa;
/* OK to have no pathname bound to the socket: happens on
every connect() unless client calls bind() first. */
if (unp->sun_path[0] == 0)
strcpy(str, "(no pathname bound)");
else
snprintf(str, sizeof(str), "%s", unp->sun_path);
return (str);
}
#endif
#ifdef HAVE_SOCKADDR_DL_STRUCT
case AF_LINK:{
struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
if (sdl->sdl_nlen > 0)
snprintf(str, sizeof(str), "%*s",
sdl->sdl_nlen, &sdl->sdl_data[0]);
else
snprintf(str, sizeof(str), "AF_LINK, index=%d",
sdl->sdl_index);
return (str);
}
#endif
default:
snprintf(str, sizeof(str),
"sock_ntop_host: unknown AF_xxx: %d, len %d",
sa->sa_family, salen);
return (str);
}
return (NULL);
}
char *Sock_ntop_host(const struct sockaddr *sa, socklen_t salen)
{
char *ptr;
if ((ptr = sock_ntop_host(sa, salen)) == NULL)
err_sys("sock_ntop_host error"); /* inet_ntop() sets errno */
return (ptr);
}
void Pipe(int *fds)
{
if (pipe(fds) < 0)
err_sys("pipe error");
}
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
ssize_t n;
if ((n = read(fd, ptr, nbytes)) == -1)
err_sys("read error");
return (n);
}
void Write(int fd, void *ptr, int nbytes)
{
if (write(fd, ptr, nbytes) != nbytes)
err_sys("write error");
}
static int pipefd[2];
static void recvfrom_alarm(int signo)
{
Write(pipefd[1], "", 1); /* write one null byte to pipe */
return;
}
void dg_cli(FILE * fp, int sockfd, const SA * pservaddr, socklen_t servlen)
{
int n, maxfdp1;
const int on = 1;
char sendline[MAXLINE], recvline[MAXLINE + 1];
fd_set rset;
socklen_t len;
struct sockaddr *preply_addr;
preply_addr = Malloc(servlen);
Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
Pipe(pipefd);
maxfdp1 = max(sockfd, pipefd[0]) + 1;
FD_ZERO(&rset);
Signal(SIGALRM, recvfrom_alarm);
while (Fgets(sendline, MAXLINE, fp) != NULL) {
Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr,
servlen);
alarm(5);
for (;;) {
FD_SET(sockfd, &rset);
FD_SET(pipefd[0], &rset);
if ((n = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
if (errno == EINTR)
continue;
else
err_sys("select error");
}
if (FD_ISSET(sockfd, &rset)) {
len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, 0,
preply_addr, &len);
recvline[n] = 0; /* null terminate */
printf("from %s: %s",
Sock_ntop_host(preply_addr, len),
recvline);
}
if (FD_ISSET(pipefd[0], &rset)) {
Read(pipefd[0], &n, 1); /* timer expired */
break;
}
}
}
free(preply_addr);
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: udpcli <IPaddress>");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(stdin, sockfd, (SA *) & servaddr, sizeof(servaddr));
exit(0);
}