socket测试-3(必做)
任务详情
基于socket 实现daytime(13)服务器(端口我们使用13+后三位学号)和客户端 服务器响应消息格式是 “ 客户端IP:XXXX 服务器实现者学号:XXXXXXXX 当前时间: XX:XX:XX ” 上方提交代码 提交一个客户端至少查询三次时间的截图测试截图 提交至少两个客户端查询时间的截图测试截图
一开始代码不对,csapp的代码输入错误
我的端口号为13216
服务器1 实现了报告三次时间
由于我的虚拟机的时间不对,所以这里显示的不是对的时间,老师可以查看我下面截图里的电脑时间
服务器2、3
总共三个服务器
client.c代码
/* * echoclient.c - An echo client */ /* $begin echoclientmain */ #include "./csapp.h" int main(int argc, char **argv) { int clientfd, port; char *host, buf[MAXLINE]; rio_t rio; if (argc != 3) { fprintf(stderr, "usage: %s <host> <port>\n", argv[0]); exit(0); } host = argv[1]; port = atoi(argv[2]); clientfd = Open_clientfd(host, port); Rio_readinitb(&rio, clientfd); while (Fgets(buf, MAXLINE, stdin) != NULL) { static char timestr[40]; time_t t; struct tm *nowtime; time(&t); nowtime = localtime(&t); strftime(timestr,sizeof(timestr),"%Y-%m-%d %H:%M:%S",nowtime); printf("客户端IP:127.0.0.1\n"); printf("服务器实现者学号:20191216"); printf("当前时间:%s\n",timestr); printf("\n"); Rio_writen(clientfd, buf, strlen(buf)); Rio_readlineb(&rio, buf, MAXLINE); Fputs(buf, stdout); } Close(clientfd); //line:netp:echoclient:close exit(0); } /* $end echoclientmain */
server.1c代码
/* * echoserverp.c - A concurrent echo server based on processes */ /* $begin echoserverpmain */ #include "csapp.h" void echo(int connfd,char *haddrp); void sigchld_handler(int sig) //line:conc:echoserverp:handlerstart { while (waitpid(-1, 0, WNOHANG) > 0) ; return; } //line:conc:echoserverp:handlerend int main(int argc, char **argv) { int listenfd, connfd, port; char *haddrp; socklen_t clientlen=sizeof(struct sockaddr_in); struct sockaddr_in clientaddr; if (argc != 2) { fprintf(stderr, "usage: %s <port>\n", argv[0]); exit(0); } port = atoi(argv[1]); Signal(SIGCHLD, sigchld_handler); listenfd = Open_listenfd(port); while (1) { connfd = Accept(listenfd, (SA *) &clientaddr, &clientlen); if (Fork() == 0) { haddrp = inet_ntoa(clientaddr.sin_addr); Close(listenfd); /* Child closes its listening socket */ echo(connfd,haddrp); /* Child services client */ //line:conc:echoserverp:echofun Close(connfd); /* Child closes connection with client */ //line:conc:echoserverp:childclose exit(0); /* Child exits */ } Close(connfd); /* Parent closes connected socket (important!) */ //line:conc:echoserverp:parentclose } } /* $end echoserverpmain */ void echo(int connfd,char *haddrp) { static char timestr[40]; time_t t; struct tm *nowtime; time(&t); nowtime = localtime(&t); strftime(timestr,sizeof(timestr),"%Y-%m-%d %H:%M:%S",nowtime); size_t n; char buf[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { //line:netp:echo:eof printf("server received %d bytes\n", (int)n); printf("客户端IP:%s\n",haddrp); printf("服务器实现者学号:20191216\n"); printf("当前时间:%s\n",timestr); printf("\n"); Rio_writen(connfd, buf, n); } }
server2.c代码
/* * echoservert.c - A concurrent echo server using threads */ /* $begin echoservertmain */ #include "csapp.h" void echo(int connfd); void *thread(void *vargp); char *haddrp; int main(int argc, char **argv) { int listenfd, *connfdp, port; socklen_t clientlen=sizeof(struct sockaddr_in); struct sockaddr_in clientaddr; pthread_t tid; if (argc != 2) { fprintf(stderr, "usage: %s <port>\n", argv[0]); exit(0); } port = atoi(argv[1]); listenfd = Open_listenfd(port); while (1) { connfdp = Malloc(sizeof(int)); //line:conc:echoservert:beginmalloc *connfdp = Accept(listenfd, (SA *) &clientaddr, &clientlen); //line:conc:echoservert:endmalloc haddrp = inet_ntoa(clientaddr.sin_addr); Pthread_create(&tid, NULL, thread, connfdp); } } /* thread routine */ void *thread(void *vargp) { int connfd = *((int *)vargp); Pthread_detach(pthread_self()); //line:conc:echoservert:detach Free(vargp); //line:conc:echoservert:free echo(connfd); Close(connfd); return NULL; } /* $end echoservertmain */ void echo(int connfd) { static char timestr[40]; time_t t; struct tm *nowtime; time(&t); nowtime = localtime(&t); strftime(timestr,sizeof(timestr),"%Y-%m-%d %H:%M:%S",nowtime); size_t n; char buf[MAXLINE]; rio_t rio; Rio_readinitb(&rio, connfd); while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0) { //line:netp:echo:eof printf("server received %d bytes\n", (int)n); printf("客户端IP:%s\n",haddrp); printf("服务器实现者学号:20191216\n"); printf("当前时间:%s\n",timestr); printf("\n"); Rio_writen(connfd, buf, n); } }
Linux下创建一个线程可以调用pthread_create()
函数来创建线程,int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);
,其中第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。