unp學習筆記——Chapter1

中大黑熊發表於2014-05-26

1.發現網路拓撲的幾個重要的命令

(1).netstat -i 提供網路介面的資訊。我們還指定-n 標誌以輸出數值地址,而不是試圖把它們反向解析成名字。netstat -r 展示路由表。

dzhwen@deng:~/unpv13e/intro$ netstat -ni
Kernel Interface table
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500 0         0      0      0 0             0      0      0      0 BMU
eth1       1500 0     13924      5      0 0         15296      9      0      0 BMRU
lo        65536 0      1207      0      0 0          1207      0      0      0 LRU
dzhwen@deng:~/unpv13e/intro$ netstat -nr
核心 IP 路由表
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG        0 0          0 eth1
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth1
192.168.0.0     0.0.0.0         255.255.255.0   U         0 0          0 eth1

 

(2).通過ifconfig獲得每個介面的詳細資訊。

dzhwen@deng:~/unpv13e/intro$ ifconfig eth0
eth0      Link encap:乙太網  硬體地址 e8:11:32:ca:7d:6f  
          UP BROADCAST MULTICAST  MTU:1500  躍點數:1
          接收資料包:0 錯誤:0 丟棄:0 過載:0 幀數:0
          傳送資料包:0 錯誤:0 丟棄:0 過載:0 載波:0
          碰撞:0 傳送佇列長度:1000 
          接收位元組:0 (0.0 B)  傳送位元組:0 (0.0 B)
dzhwen@deng:~/unpv13e/intro$ ifconfig eth1
eth1      Link encap:乙太網  硬體地址 90:a4:de:b0:90:23  
          inet 地址:192.168.0.105  廣播:192.168.0.255  掩碼:255.255.255.0
          inet6 地址: fe80::92a4:deff:feb0:9023/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  躍點數:1
          接收資料包:22937 錯誤:6 丟棄:0 過載:0 幀數:114848
          傳送資料包:22285 錯誤:9 丟棄:0 過載:0 載波:0
          碰撞:0 傳送佇列長度:1000 
          接收位元組:23754977 (23.7 MB)  傳送位元組:3331047 (3.3 MB)
          中斷:16 

 

(3).通過ping廣播地址來獲取網路拓撲

dzhwen@deng:~/unpv13e/intro$ ping -b 192.168.0.255

 

 習題:

1.5.修改客戶端和伺服器程式,使得客戶端加入一個計數器,累計read返回大於零值的次數。在終止前輸出這個計數器值,同時把伺服器的write的單一呼叫改成迴圈呼叫。

注意:修改程式本身並不複雜,但我們要對最原始的阻塞式的I/O模型要有一定的理解。我們知道在客戶端中的計數器自增是原子型操作,當資料包準備好複製資料包時,客戶端再將資料從核心複製到使用者空間。複製完成後,客戶端程式像核心返回成功指示,這時才會在程式上顯示相應的資料,並處理資料等等。

因此回到本題,如果我們要使客戶端能記錄下來,在伺服器端傳送訊息就不能太快,否則客戶端會一次read掉伺服器多次write的資料。因此,最好在伺服器每傳送一個字元後休眠一秒。

客戶端:

#include    "unp.h"

int
main(int argc, char **argv)
{
    int                    sockfd, n,num = 0;
    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(8888);    /* 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) {
        //sleep(1);
        num++;   //exercise 1.4
        recvline[n] = 0;    /* null terminate */
        
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (n < 0)
        err_sys("read error");

    //Exercise 1.4
    printf("Num is %d\n",num);
    //Exercise 1.4
    
    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(8888);    /* 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\r\n", ctime(&ticks));
        char* pr = buff;
        size_t len = strlen(buff),num = 0;
        for(;num < len;++num,++pr){
            Write(connfd, buff+num,1);
            sleep(1);
        }
        Close(connfd);
    }
}
dzhwen@deng:~/unpv13e/intro$ ./testsrv
dzhwen@deng:~/unpv13e/intro$ ./test 127.0.0.1
Mon May 26 20:54:44 2014
Num is 26

多多指教!