第8周课堂测试3(课上未完成)

课上练习3:基于socket 使用教材的csapp.h csapp.c,实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端

服务器响应消息格式是

“客户端IP:XXXX

服务器实现者学号:XXXXXXXX

当前时间: XX:XX:XX”

实现daytime服务器和客户端:

完成这个作业首先要复习并仔细阅读第11章,针对11章里的示例代码,写了一篇博客分析每句代码和函数。第11章代码详解

参考书上P662,echo客户端和服务器的示例,编译书上的示例就遇到一堆问题。

  1. 需要先从网上下载随书源代码,将csapp.h头文件复制到工作目录下,但这样仍然无法在main函数中找到相关函数定义。

image

  1. 将csapp.c文件复制到工作目录下,因为csapp.h头文件中的函数定义具体实现是在csapp.c中的,然后通过分步编译得到csapp.o 和 serveri.o,再进行链接。
  2. csapp.c里包含pthread多线程编程的一些函数,在编译时,需要加上参数“-pthread”。

image

  1. 服务器和客户端都编译完成后,得到两个server、client两个可执行文件,但一运行就连接失败。

image

  1. 仔细看Open_clientfd这个函数,发现因为是csapp.c用的是第二版书的代码,所以在定义端口时,csapp.c中用的int型,而第三版书上echoserveri.c中端口用的字符串。导致连接不成功。

解决办法:用atoi函数将传入的字符串参数转为int型参数,再传入Open_clientfd函数。

  1. 修改后再运行又出现客户端拒绝访问(permission denied)

解决办法:用sudo命令运行客户端,成功运行。

image

  1. 再打开客户端,瞬间成功连接上服务器。不断从客户端输入文本,并发送到服务器,服务器读取并回送,再从客户端标准输出。

image

然后,基于这个示例,我们只需修改服务器功能,让服务器按格式返回时间即可。

用老师教的man -K大法

 man 2 -K time

image

但time函数得到的系统时间是秒数,需要转换一下格式。

time函数的SEE ALSO里给我们提示,继续用man -K搜索gmtime

image

gmtime是一个指针函数,返回一个指向struct tm结构体类型的指针。

image

修改服务器echo函数:

void echo(int connfd, char *haddrp)//客户端IP
{
    time_t t; 
    struct tm * lt;

    size_t n; 
    char buf[MAXLINE]; 
    rio_t rio;

    Rio_readinitb(&rio, connfd);
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { 
    printf("\n客户端IP:%s\n",haddrp);
    printf("服务器实现者学号:20155225\n");
    time (&t);
    lt = gmtime (&t);
    printf ("当前时间为:%d/%d/%d %d:%d:%d\n",lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
	//Rio_writen(connfd, buf, n);
    }
}

编译过程中仍然存在问题,修改echo函数后,对eho函数说明和引用都需要修改参数。

image

最后成功实现了time服务器和客户端,如下图所示。

image

posted on 2017-12-10 14:31  20155225江智宇  阅读(378)  评论(0编辑  收藏  举报