unp学习笔记——Chapter1

本文介绍如何使用netstat和ifconfig等命令发现网络拓扑结构,包括网络接口信息、路由表及详细接口状态。同时,通过修改客户端和服务器程序,深入理解阻塞式I/O模型,确保服务器发送消息与客户端读取之间的同步。
摘要由CSDN通过智能技术生成

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

多多指教!
 

转载于:https://www.cnblogs.com/sysu-blackbear/p/3753247.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值