• 课下测试二


    首先是完成课堂测试3

    基于socket 使用教材的csapp.h,和csapp.c实现daytime(13)服务端(端口我们是用的是13+后三位学号)和客户端,以下是服务器相应格式。

    首先我们要写的是客户端的代码:

    #include    "unp.h"
      
      int
      main(int argc, char **argv)
      {
           int                 sockfd, n;
          char                recvline[MAXLINE + 1];
          struct sockaddr_in  servaddr;
      
        if (argc != 2)
            err_quit("usage: a.out <IPaddress>");
     
         if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
              err_sys("socket error");
     
         bzero(&servaddr, sizeof(servaddr));
         servaddr.sin_family = AF_INET;
         servaddr.sin_port   = htons(13);    /* daytime server */
          if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
              err_quit("inet_pton error for %s", argv[1]);
     
          if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
              err_sys("connect error");
     
          while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
             recvline[n] = 0;    /* null terminate */
             if (fputs(recvline, stdout) == EOF)
                 err_sys("fputs error");
        }                                                                                                               
        if (n < 0)
             err_sys("read error");
             
         exit(0);
     }
    

    客户端的程序主要是向服务器发送连接请求,建立连接之后,然后读取从服务器传回来的数据。

    接下来是服务器的代码

      #include    "unp.h"                                                                                               
       #include    <time.h>
      
      int
       main(int argc, char **argv)
      {
          int                 listenfd, connfd;
          struct sockaddr_in  servaddr;
           char                buff[MAXLINE];
         time_t              ticks;
     
          listenfd = Socket(AF_INET, SOCK_STREAM, 0);
     
          bzero(&servaddr, sizeof(servaddr));
          servaddr.sin_family      = AF_INET;
         servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
         servaddr.sin_port        = htons(13);   /* daytime server */
         Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
     
          Listen(listenfd, LISTENQ);
     
         for ( ; ; ) {
             connfd = Accept(listenfd, (SA *) NULL, NULL);
             ticks = time(NULL);
              snprintf(buff, sizeof(buff), "%.24s
    ", ctime(&ticks));
              snprint(buff,sizeof(buff),"客户端Ip:127.0.1
    服务器实现者学号:20155309
    当前时间:%.24s
    ",crime(&ticks));
             Write(connfd, buff, strlen(buff));
             Close(connfd);
          }
      }
    

    问题及解决

    代码不能够运行?

    我仔细的检查了客户端与服务器的代码之后,发现

    切换到root用户下执行:

    # ./configure     //在unpv13e当前目录下执行configure
    # cd lib       //然后进入 lib目录,make一下编译环境
    # make
    

    前期准备工作完成了

    然后在 ./intro/目录下有原始版本的 daytimetcpcli.c(client源码) 以及daytimetcpsrv.c (server端源码);
    如果没有两台服务器的话,那么我们就在同一台服务器下面开两个进程(终端),其中一个作为server:

    # cd intro/
    # make daytimetcpsrv
    # ./daytimetcpsrv           // 编译完之后,运行,server端就开始监听了。
    

    一个进程作为client:

    # cd intro/
    # make daytimetcpcli
    # ./daytimetcpcli 127.0.0.1      //因为是在同一台主机上测试,所ip地址取127也可以取本地实际的地址,因为我的是在虚拟机下,所以192的ip也没什么意义。
    

    然后就可以看到客户端以及将服务器端的server拿回了。至此一个简单而典型的socket程序就部署成功了。

    这样我们就可以运行代码了。

    课下关于多线程的作业:

    echoserveri.c :
    
    /* 
     * echoserveri.c - An iterative echo server 
     */ 
    /* $begin echoserverimain */
    #include "csapp.h"
    
    void echo(int connfd);
    
    int main(int argc, char **argv) 
    {
        int listenfd, connfd, port, clientlen;
        struct sockaddr_in clientaddr;
        struct hostent *hp;
        char *haddrp;
        if (argc != 2) {
        fprintf(stderr, "usage: %s <port>
    ", argv[0]);
        exit(0);
        }
        port = atoi(argv[1]);
    
        listenfd = Open_listenfd(port);
        while (1) {
        clientlen = sizeof(clientaddr);
        connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
    
        /* determine the domain name and IP address of the client */
        hp = Gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, 
                   sizeof(clientaddr.sin_addr.s_addr), AF_INET);
        haddrp = inet_ntoa(clientaddr.sin_addr);
        printf("server connected to %s (%s)
    ", hp->h_name, haddrp);
    
        echo(connfd);
        Close(connfd);
        }
        exit(0);
    }
    /* $end echoserverimain */
    
    
    
    
    echoclient.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>
    ", 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) {
        Rio_writen(clientfd, buf, strlen(buf));
        Rio_readlineb(&rio, buf, MAXLINE);
        Fputs(buf, stdout);
        }
        Close(clientfd);
        exit(0);
    }
    /* $end echoclientmain */
    

    修改后的代码为:

    /*
     * 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>
    ", 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) {
        
        time_t t;
        struct tm * lt;
        size_t n; 
        printf("
    客户端IP:127.0.0.1
    ");
        printf("服务器实现者学号:20155309
    ");
        
        time (&t);
        lt = localtime (&t);
        printf ("当前时间为:%d/%d/%d %d:%d:%d
    ",lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
        Rio_writen(clientfd, buf, strlen(buf));
        Rio_readlineb(&rio, buf, MAXLINE);
        Fputs(buf, stdout);
        }
        Close(clientfd); //line:netp:echoclient:close
        exit(0);
    }
    /* $end echoclientmain */
    

    关于多线程的思考

    Lock(锁定):作用于主内存中的变量,把一个变量标识为一条线程独占的状态。

    Read(读取):作用于主内存中的变量,把一个变量的值从主内存传输到线程的工作内存中。

    Load(加载):作用于工作内存中的变量,把read操作从主内存中得到的变量的值放入工作内存的变量副本中。

    Use(使用):作用于工作内存中的变量,把工作内存中一个变量的值传递给执行引擎。

    Assign(赋值):作用于工作内存中的变量,把一个从执行引擎接收到的值赋值给工作内存中的变量。

    Store(存储):作用于工作内存中的变量,把工作内存中的一个变量的值传送到主内存中。

    Write(写入):作用于主内存中的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中。

    Unlock(解锁):作用于主内存中的变量,把一个处于锁定状态的变量释放出来,之后可被其它线程锁定。

  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    ajax如何处理服务器返回的三种数据类型
    JavaScript中常见排序算法详解
    《JavaScript语言精粹》读书笔记——给类型增加方法一节的疑问
    前端常见跨域解决方案(全)
    ACE模板的布局简介
    ES6学习笔记---对象的扩展
    偏振
    欧拉赞词
    狄拉克δ函数的导数
  • 原文地址:https://www.cnblogs.com/nhx19970709/p/7822705.html
Copyright © 2020-2023  润新知