您的位置:首页 > 理论基础 > 计算机网络

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

2017-03-23 14:51 323 查看

前言

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


关注点

unp.h头文件

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

一个简单的时间获取服务器

测试网络及主机

64位体系结构

1. unp.h头文件

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


如何使用unp.h头文件

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


cd unpv13e
./configure
cd lib
make


这样在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
= 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();

零碎细节

\r Mac回车符

\n Unix换行

\r\n Windows下换行符

引用网上的图片:



客户端采用while循环读取数据的原因:

TCP是面向字节流的协议,数据由于各种各样的原因(如Nagle算法)会无法一次性发送到接收端,因此,客户端要直到read返回0的时候(表明对方关闭链接)才能终止连接。(因此这是一个服务器主动关闭连接的例子,服务器将出现TIME_WAIT状态)

exit终止程序运行。Unix在一个进程终止时总是关闭该进程所有打开的描述符。

Unix errno值

只要一个unix函数中有错误发生,全局变量errno就被置为一个指明该错误类型的正值,函数本身则放回-1.

常见c函数

snprintf vs sprintf
fgets vs gets
str
4000
ncat vs strcat
strncpy vs strcpy
strlcat vs strncat
strlcpy 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位不变。**
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  网络编程 unix