运行书本中的程序。
方法一、
1,首先,下载源码:unpv13e.tar.gz
2,然后,编译程序,方法如下:(具体编译方法可以看unpv13e中的README文档)
tar -zxvf unpv13e.tar.gz (-C dir)//解压文件
cd unpv13e
./configure # try to figure out all implementation differences
cd lib # build the basic library that all programs need
make # use "gmake" everywhere on BSD/OS systems
cd ../libfree # continue building the basic library
make
cd ../libroute # only if your system supports 4.4BSD style routing sockets
make # only if your system supports 4.4BSD style routing sockets
cd ../libxti # only if your system supports XTI
make # only if your system supports XTI
(在我的电脑上这两个make没有通过,也不要紧,看后面的注释可以看到它们对应于特定的平台才会通过,这里不影响我们编译该客户端服务器时间日期程序)
接着往下:
cd ../intro # build and test a basic client program
make daytimetcpsrv
此时会生成 daytimetcpsrv daytimetcpsrv.o
<用gcc -o daytimetcpsrv daytimetcpsrv.c编译会出错>
(这一步在README文件中没有写出,要注意!!!!假如我们没有执行make daytimetcpsrv,而是直接执行make daytimetcpcli,然后输入 ./daytimetcpcli 127.0.0.1 后发现报错;Connection Refused。上网google了一下解决了这个问题,原来是因为这个版本的系统默认是不开daytime服务的,而且开启daytime服务需要有root权限,然后你会看到在相同的目录下有一个daytimetcpsrv.c文件,编译(make daytimetcpsrv)后执行它,注意需要有root权限,即sudo ./daytimetcpsrv。它的功能就是开启本机的daytime服务,然后你再开启一个终端,敲击./daytimetcpcli 127.0.0.1后返回了你想要的结果。
make daytimetcpcli
<用gcc -o daytimetcpcli daytimetcpcli.c编译会出错>
此时会生成 daytimetcpcli daytimetcpcli.o
3、linux现在因为安全问题,各个发行版本默认是不开daytime服务的。
第一个例子实际上是两个程序,客户端和服务端,你很有可能只运行了客户端,没有运行服务端程序。
服务端程序在书上第12页……你不会尚还没有看到那里吧?
PS:由于要打开端口,所以服务端程序需要用root权限执行,所以你可以先
sudo ./daytimetcpsrv (如果本身就是root就不需要sudo)<要打开小于1024端口的服务,要用root才能执行>
然后再开一个终端运行 ./daytimetcpcli 127.0.0.1 就可以看到返回的时间了
方法二、自己编写代码
自己编写的包裹函数代码如下:
-
//unp.h
-
#include<sys/socket.h>
-
#include<stdlib.h>
-
-
#define SA struct sockaddr
-
#define LISTENQ 1024
-
-
int Socket(int family,int type,int protocol)
-
{
-
int n;
-
if((n=socket(family,type,protocol))<0)
-
{
-
printf("socket error");
-
exit(-1);
-
}
-
printf("baoguohanshutiaoyongle\n");
-
return n;
-
}
-
-
int Bind(int sockfd,const struct sockaddr*myaddr,socklen_t addrlen)
-
{
-
int n;
-
if((n=bind(sockfd,myaddr,addrlen))<0)
-
{
-
printf("bind error\n");
-
exit(-1);
-
}
-
return n;
-
}
-
-
-
int Connect(int sockfd,const struct sockaddr*servaddr,socklen_t addrlen)
-
{
-
int n;
-
if(( n=connect(sockfd,servaddr,addrlen)<0)
-
{
-
printf("connect to server error\n");
-
exit(-1);
-
}
-
return n;
-
}
-
-
-
int Accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen)
-
{
-
int n;
-
if((n=accept(sockfd,cliaddr,addrlen))<0)
-
{
-
printf("accept error\n");
-
exit(-1);
-
}
-
return n;
-
}
daytimetcpcli.c代码如下:
-
#include<stdlib.h>
-
#include<stdio.h>
-
#include<unistd.h>
-
#include<strings.h>
-
#include<sys/socket.h>
-
#include<netinet/in.h>
-
#include "unp.h"
-
-
#define MAXLINE 4096
-
-
int main(int argc,char **argv)
-
{
-
int sockfd,n;
-
struct sockaddr_in servaddr;
-
char recvline[MAXLINE+1];
-
-
if(argc!=2)
-
{
-
printf("usage:a.out ");
-
exit(-1);
-
}
-
-
sockfd=Socket(AF_INET,SOCK_STREAM,0);
-
-
bzero(&servaddr,sizeof(servaddr));
-
servaddr.sin_family=AF_INET;
-
servaddr.sin_port=htons(13);
-
if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<=0)
-
{
-
printf("inet_pton error for %s\n",argv[1]);
-
exit(-1);
-
}
-
-
Connect(sockfd,(SA*)&servaddr,sizeof(servaddr));
-
-
while((n=read(sockfd,recvline,MAXLINE))>0)
-
{
-
printf("read %d words from sockfd\n",n);
-
recvline[n]=0;
-
if(fputs(recvline,stdout)==EOF)
-
{
-
printf("fputs error\n");
-
exit(-1);
-
-
}
-
-
}
-
if(n<0)
-
{
-
printf("read error\n");
-
exit(-1);
-
}
-
exit(0);
-
}
daytimetcpserv.c代码如下:
-
#include<stdlib.h>
-
#include<stdio.h>
-
#include<unistd.h>
-
#include<time.h>
-
#include<string.h>
-
#include<strings.h>
-
#include "unp.h"
-
#include<netinet/in.h>
-
#include<sys/socket.h>
-
-
#define LISTENQ 1024
-
#define MAXLINE 4096
-
-
int main(int argc,char **argv)
-
{
-
int n;
-
int listenfd,connfd;
-
time_t ticks;
-
socklen_t len;
-
char buff[MAXLINE];
-
struct sockaddr_in cliaddr,servaddr;
-
-
listenfd=Socket(AF_INET,SOCK_STREAM,0);
-
-
bzero(&servaddr,sizeof(servaddr));
-
-
servaddr.sin_family=AF_INET;
-
servaddr.sin_port=htons(13);
-
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
-
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));
-
n= write(connfd,buff,strlen(buff));
-
printf("actually write %d words to connfd\n",n);
-
close(connfd);
-
}
-
}
注意:小于1024的端口要有root权限才能带开,因此在运行服务器端时,要切换为root用户。或者是有sudo是普通用户有root权限也可以。
阅读(348) | 评论(0) | 转发(0) |