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);,其中第一个参数为指向线程标识符的指针。

第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。

posted @ 2021-12-20 11:34  zzy188  阅读(164)  评论(0编辑  收藏  举报