[UNIX网络编程1.0]源代码在linux系统下的实现
之前一直想自学unix网络编程,还特地去买了本史蒂文斯的书。没想到一开始就被那个简单的时间获取客户程序搞晕了。试了N中方式把网上的教程翻了个便都不行。甚至有一段时间故意不去看它。
关键就在unp.h,怎么把它编译成功。
#include "unp.h" //#include "myerr.h" int main(int argc, char **argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage: a.out <IPaddress>"); if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_sys("socket error"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(13); /* daytime server */ if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) err_quit("inet_pton error for %s", argv[1]); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) err_sys("connect error"); while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) err_sys("fputs error"); } if (n < 0) err_sys("read error"); exit(0); }
直至今天重新打开ubuntu。静下心来把过程在走一遍。
第一步,下载源程序及其配置文件unpv13e。把它放在任意的目录中,因为里边已经包含了上边的daytimetcpcli.c的文件在intro文件夹下。所以不需要再重新编写考虑放到那的问题了。
第二步,找到readme文件,照做。
Execute the following from the src/ directory:
./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
cd ../intro # build and test a basic client program
make daytimetcpcli
./daytimetcpcli 127.0.0.1
If all that works, you're all set to start compiling individual programs.
切换到根目录先./configure一下。
第三步,成功以后进入lib目录,执行make命令。
这时候基本上unp.h已经编译好了。进入daytimetcpcli.c所在的文件夹(intro)gcc一下 daytimetcpcli.c。
此时会提示:
undefined reference to 'err_quit'
undefined reference to 'err_sys'
错误,因为在程序里我们用到err_quit("usage: a.out <IPaddress>");这些出错处理的方法。
第四步,解决方法,网上普遍提供的是新建一个myerr.h的头文件然后把方法的定义加入到该文件中然后将其copy到usr/include文件夹下,接着在daytimetcpcli.c中include进去。不知道为什么当我用这种方法是他总会提示与error.c中的方法重复定义了。但如果不include进去,就是提示错误。
后来就找到了第二种方法。直接在编译的时候吧error.c编译进去。命令行直接输入gcc daytimetcpcli.c error.c -o daytimetcpcli 。执行后终于不再报错。
这时候daytimetcpcli.c完全可以编译成功了。
第五步,但这毕竟只是一个客户端程序,要想完成时间获取,还要运行相应的服务器端。幸好下载的unpv13e的源文件里有这个文件。
重新打开一个终端,gcc一下daytimetcpsrv.c,然后运行。服务器端运行以后,客户端./一下 daytimetcpcli。不巧的是此时提示Connection Refused。网上搜了一下,原来是daytime服务未开启。开启服务需要root权限。
第六步,开启daytimef服务。相对比较简单,在root权限下执行命令:
sudo apt-get install xinetd
sudo vi /etc/xinetd.d/daytime, 将 disable = yes 改为 no
sudo /etc/inet.d/xinetd restart
最后一步是重启。
这时候在服务器端重新运行daytimetcpsrv。此时客户端在此运行还是出现连接失败。
于是网上找原因。原来时daytime服务需要root权限,所以在执行服务器端程序是加一个sudo就可以了。
最后
总结一句话,一个人摸索的时候总会遇到各种各样的困难,这些困难可能以前别人遇到过,可能从来没人遇到过。但不能失掉了勇气和信心。不能因此失掉了兴趣。这时候你要做的是静下心来,把思路捋一遍再捋一遍。