《UNIX网络编程卷1》读书笔记--第一章 简介和TCP/IP

来源:互联网 发布:电子公章制作软件 编辑:程序博客网 时间:2024/05/21 18:47

前言

正如标题所说,第一章是对本书和TCP/IP的简介。简要介绍了网络通信的基本流程、简单socket客户端、服务端程序的编写,以及全书计算机运行的网络环境。

关注点

  • unp.h头文件
  • 一个简单的时间获取客户程序
  • 一个简单的时间获取服务器
  • 测试网络及主机
  • 64位体系结构

1. unp.h头文件

unp.h头文件包含了大多数网络程序都需要的所有标准头文件以及一些普通的系统头文件。它还定义了诸如MAXLINE等常值。并定义了书中正文定义过的函数以及所用到的所有包裹函数的ANSI C函数原型。

如何使用unp.h头文件

在[这里](http://www.unpbook.com) 下载得到unpv13e。
cd unpv13e./configurecd libmake

这样在unp13e目录下就获得了lib(文件夹中生成.o文件)、config.h、libunp.a

应用例子

目录结构如下:
daytimetcpcli.c
lib
config.h
libunp.a

gcc daytimetcpcli.c -o daytimetcpcli -L. -lunp -I./lib

这样就可以生成daytimetcpcli(不过暂时没有开服务端,connect会发生错误)

2. 一个简单的时间获取客户程序

#include "unp.h"int main(int argc, int **argv){    int sockfd, n;    char recvline[MAXLINE + 1]; //notice MAXLINE+1    struct sockaddr_in servaddr;    if(argc != 2)        err_quit("usage: ...");    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)        err_sys("socket create error");    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(13);    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)) == -1)        err_sys("connect error");    while((n = read(sockfd, recvline, MAXLINE)) > 0){        recvline[n] = 0;        if(fputs(recvline, stdout) == EOF)            err_sys("fputs error");    }    if(n < 0)        err_sys("read error");    if(n == 0)        err_sys("shutdown connection");    exit(0);}

3. 一个简单的时间获取客户程序

#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\r\n", ctime(&ticks));        Write(connfd, buff, strlen(buff));        Close(connfd);    }}
总结2,3:这两个简单的程序涵盖了socket API客户端,服务端设计的基本操作。服务器端采用for循环来接收客户端的连接,是一个典型的迭代服务器。

这里写图片描述

除此之外一些值得注意的函数:

bzero(), htons(), htonl(), inet_pton(), connect(), read(), write(), fputs(), snprintf();

零碎细节

  1. \r Mac回车符
    \n Unix换行
    \r\n Windows下换行符
    引用网上的图片:
    这里写图片描述
  2. 客户端采用while循环读取数据的原因:
    TCP是面向字节流的协议,数据由于各种各样的原因(如Nagle算法)会无法一次性发送到接收端,因此,客户端要直到read返回0的时候(表明对方关闭链接)才能终止连接。(因此这是一个服务器主动关闭连接的例子,服务器将出现TIME_WAIT状态)
  3. exit终止程序运行。Unix在一个进程终止时总是关闭该进程所有打开的描述符。
  4. Unix errno值
    只要一个unix函数中有错误发生,全局变量errno就被置为一个指明该错误类型的正值,函数本身则放回-1.
  5. 常见c函数
snprintf vs sprintf fgets vs getsstrncat vs strcatstrncpy vs strcpystrlcat vs strncatstrlcpy vs strncpy

详情可以看这篇博客。
6. time 和 ctime
time函数返回1970年1月1号00:00到现在的秒数
ctime转化成我们可读的时间。

4. 网络拓扑的发现

netstat、ifconfig和ping
netstat用于显示IP、TCP、UDP、ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。例如:

列出所有端口(包括监听和未监听的):netstat -a列出所有TCP端口:netstat -at列出所有UDP端口:netstat -au列出所有处于监听状态的socket:netstat -l列出所有处于监听TCP端口的socket:netstat -lt在netstat输出中显示PID和进程名称:netstat -p展示路由表:netstat -r

ifconfig可以获得每个接口的详细信息。
ping从ifconfig得出的广播接口可以获得这个子网内的各个主机的地址。

5. 64位体系结构

LP64位只有long(L)和Point(P)是64位其他的char short int 都依次是8 16 32位不变。**

1 0
原创粉丝点击