unp学习笔记
unp源码获取与编译时间获取客户端启动流程时间获取客户端测试结果
unp源码获取与编译
源码获取、解压流程如下:
wget http://www.unpbook.com/unpv13e.tar.gz
tar -zxvf unpv13e.tar.gz
源码编译,建议先查看源码中的 README
# README 部分内容如下:
QUICK AND DIRTY
===============
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.
Notice that all the source code assumes tabs every 4 columns, not 8.
MORE DETAILS
......
按照源码流程编译
cd unpv13e
./configure
cd lib
make
cd ../libfree
make
cd ../libxti
make
cd ../intro
make daytimetcpcli
./daytimetcpcli 127.0.0.1
solve1 错误提示的内容大概是:inet_ntop.c 中60行声明与原型申明 /usr/include/arpa/inet.h不匹配; 解决方法: 在 inet.h 中将 size_t 定义成 socklen_t,即在 /usr/include/arpa/inet.h 中添加下面这句话
#define size_t socklen_t
solve2 出现问题的原因可能是没安装 xinetd 或者 daytime 服务程序没开
sudo apt-get install xinetd
vim /etc/xinetd.d/daytime
(修改
...)
service xinetd restart
时间获取客户端启动流程
程序的流程如下:
声明相关结构体、变量创建网际字节流套接字将工作类型、IP地址、端口号填入套接字(IP地址点分制转换成正确格式)建立TCP连接读取数据输出数据
每个步骤的关键结构体、函数如下
step
1: struct sockaddr_in
step
2: socket(AF_INET
, SOCKSTREAM
, 0)
step
3: htons(端口号
)
inet_pto(AF_INET
, 源字符串地址
, 目的字符串地址
)
step
4: connect(sockfd
, IP地址的地址
, ip地址的长度
)
step
5: read(sockfd
, 存放地址
, 读取长度
)
step
6: fputs(存放地址
, stdout)
时间获取客户端
#include <stdio.h>
#include <unp.h>
void err_log(int numb
, char * s
);
int
main(int argc
, char *argv
[]){
int sockfd
, n
;
char recvline
[MAXLINE
+ 1];
struct sockaddr_in sadd
;
if (argc
!= 2)
err_log(-1, "usage: get_server_time <IPaddress>");
if ((sockfd
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0)
err_log(-2, "socket error");
memset(&sadd
, 0, sizeof(sadd
));
sadd
.sin_family
= AF_INET
;
sadd
.sin_port
= htons(13);
if (inet_pton(AF_INET
, argv
[1], &sadd
.sin_addr
) <= 0)
err_log(-1, "inet_pton error for this ip");
if (0 > connect(sockfd
, (struct sockaddr
*)&sadd
, sizeof(sadd
)))
err_log(-2, "connect error");
while ( (n
= read(sockfd
, recvline
, MAXLINE
)) > 0) {
recvline
[n
] = 0;
if (fputs(recvline
, stdout) == EOF)
err_log(-2, "fputs error");
}
if (n
< 0)
err_log(-2, "read error");
exit(0);
}
void
err_log(int numb
, char * s
) {
printf("%s\n", s
);
switch (numb
)
{
case -1:
exit(-1);
case -2:
exit(-2);
default:
exit(numb
);
}
}
测试结果
22 MAY 2019 21:06:40 CST