unp学习笔记之时间获取客户端(001)

    xiaoxiao2022-07-07  169

    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 # 下面 make 可能会出现问题, 解决办法见 下方solve1 cd ../libfree make # libroute 一般不编译 cd ../libxti make # 通常可以直接 make 编译出可执行文件 cd ../intro make daytimetcpcli # 执行可能会出现 connect error: Connection refused # 解决办法见 solve2 ./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 中添加下面这句话 // 添加在头文件之后 // inet.h为只读文件,需要sudo vim 或 sudo nano 才能修改 #define size_t socklen_t solve2 出现问题的原因可能是没安装 xinetd 或者 daytime 服务程序没开 # 安装 xinetd sudo apt-get install xinetd # 打开 daytime文件,将两个disable = yes 修改成 disable = no vim /etc/xinetd.d/daytime (修改...) # 修改后许重启 xinetd 服务 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, 源字符串地址, 目的字符串地址) //转换IP地址 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; //struct hostent * hp; /*判断系统输入参数*/ if (argc != 2) err_log(-1, "usage: get_server_time <IPaddress>"); /*socket创建一个网际(AF_INET) 字节流(SOCK_STREAM) 套接字*/ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err_log(-2, "socket error"); /*初始化结构体*/ memset(&sadd, 0, sizeof(sadd)); /*将服务器的工作类型、IP地址与端口号填入网际套接字*/ sadd.sin_family = AF_INET; sadd.sin_port = htons(13); // day time server if (inet_pton(AF_INET, argv[1], &sadd.sin_addr) <= 0) // 将点分制ip转换成正确格式,递给 sockaddr_in 中的 sin_addr err_log(-1, "inet_pton error for this ip"); /*build a TCP connect, and determine if the link is established*/ if (0 > connect(sockfd, (struct sockaddr *)&sadd, sizeof(sadd))) err_log(-2, "connect error"); /*read data*/ while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; // end of string if (fputs(recvline, stdout) == EOF) err_log(-2, "fputs error"); } if (n < 0) err_log(-2, "read error"); exit(0); } // 重写一遍之后,err_sys err_exit函数无法使用 // 只好自己写了一个err_log函数替代 // 在大型项目中,可以在这个函数中将错误写入log 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
    最新回复(0)