【UNIX网络编程】第一期 简介

      呵呵,终于要开始传说中的大部头之旅了。其实Unix网络编程这本书12年暑假就买了,可是当时的网络知识一穷二白,而且也有各种事情,所以卷1和卷2连塑料膜都没有划开就被我供奉在了书架上,直到现在... 大三上的时候学习了Computer Network和Operating System,觉得基础已经积累得差不多了,那么,就开始吧。

      【PS】小舟呢很喜欢听广播剧,那么也就仿照广播剧的样式,来个第n期第n期的吧。不怕慢,就怕断啊~希望能坚持到出完结篇!不想挖坑,握拳!

-------------------------------------------------------我是开始填坑的分界线------------------------------------------

一、概述

       要编写通过计算机网络进行通信的程序,首先要确定它们之间用于通信的协议(protocol).

       网络应用多采用C/S结构来组织。 客户(用户进程) <---协议--->服务器(服务器进程)

       本书的焦点是TCP/IP协议族。

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

View Code
 1 #include    "unp.h"
 2 
 3 int
 4 main(int argc, char **argv)
 5 {
 6     int                    sockfd, n;
 7     char                recvline[MAXLINE + 1];
 8     struct sockaddr_in    servaddr;
 9 
10     if (argc != 2)
11         err_quit("usage: a.out <IPaddress>");
12     //socket函数创建一个网际(AF_INET)字节流套接字(SOCK_STREAM),其实就是TCP套接字。
13     //生成一个整数描述符,之后connect和read就用该描述符来标识这个套接字
14     if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
15         err_sys("socket error");
16     
17     //把服务器额IP地址和端口号填入一个网际套接字结构(一个名为servaddr的sockaddr_in结构变量)
18     bzero(&servaddr, sizeof(servaddr));
19     servaddr.sin_family = AF_INET;
20     //网际套接字结构结构中IP地址和端口号必须使用特定格式,调用库函数htons(host to network shortint)转换端口
21     servaddr.sin_port   = htons(13);    /* daytime server */
22     if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)//调用inet_pton("呈现形式到数值")转换IP
23         err_quit("inet_pton error for %s", argv[1]);
24 
25     if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
26         err_sys("connect error");
27 
28     while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {//read返回0时说明读取完毕
29         recvline[n] = 0;    /* null terminate */
30         if (fputs(recvline, stdout) == EOF)
31             err_sys("fputs error");
32     }
33     if (n < 0)
34         err_sys("read error");
35 
36     exit(0);
37 }

三、协议无关性
      上面的协议只是适用于IPv4,如果需要支持IPv6需要修改程序代码。-->更好的做法是编写协议无关性程序。

四、错误处理:包裹函数

      程序都必须检查每个函数调用是否返回错误。在函数调用发生处错误时,调用自己的err_quit或是err_sys函数输出一个出错消息并终止函数的执行。这是我们经常要做到的事儿,所以我们可以通过定义包裹函数(wrapper function)来缩短程序。包裹函数完成实际的函数调用,检查返回值,并在发生错误时终止进程。

       ##Unix errno值

       一个Unix函数发生错误时,全局变量errno会被置为一个指明该错误类型的正值,函数本身返回-1。err_sys函数可以查看errno变量的值并输出相应的出错消息。errno值只在发生错误时设置,0值不表示任何错误。

       PS:在全局变量中存放errno值对于共享所有全局变量的多个线程并不合适。线程函数遇到错误时,把errno值作为函数返回值返回调用者。

五、一个简单的时间获取服务器程序

View Code
 1 #include    "unp.h"
 2 #include    <time.h>
 3 
 4 int
 5 main(int argc, char **argv)
 6 {
 7     int                    listenfd, connfd;
 8     struct sockaddr_in    servaddr;
 9     char                buff[MAXLINE];
10     time_t                ticks;
11 
12     //创建TCP套接字
13     listenfd = Socket(AF_INET, SOCK_STREAM, 0);
14     
15     
16     bzero(&servaddr, sizeof(servaddr));
17     servaddr.sin_family      = AF_INET;
18     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址为INADDR_ANY,若是服务器有多个网络接口,
19                                                  //服务器进程就可以在任何网络接口上接受客户连接
20     servaddr.sin_port        = htons(13);    /* daytime server */
21 
22     //把服务器众所周知的接口绑定到套接字上
23     Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
24     
25     //把套接字转换成监听套接字,使外来连接可以再该套接字上由内核接受
26     Listen(listenfd, LISTENQ);//LISTENQ:最大客户连接数
27 
28     for ( ; ; ) {
29         connfd = Accept(listenfd, (SA *) NULL, NULL);
30 
31         ticks = time(NULL);
32         //snprintf第二个参数限制缓冲区大小,可以保证缓冲区不溢出
33         snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
34         Write(connfd, buff, strlen(buff));
35     
36     //这个程序一次只能处理一个客户请求,如果要实现一对多的效果,可以使用fork为每个客户连接创建子进程;若需要长时间运行,需把程序改为一个
37     //Unix守护进程(daemon)运行
38         Close(connfd);
39     }
40 }

六、本书中C/S程序示例索引表
      这个应该是看完后面部分之后作为一个目录吧,先mark下,学完再回头看。

七、OSI模型

      OSI模型是ISO提出的。【每次看到这句话我总有一种微妙的感觉...】

八、BSD网络支持历史

     BSD考古贴,有兴趣的详细看吧。

九、测试用网络及主机

     本书网络拓扑图:

 

       几个Unix网络基本命令:

(1)netstat -ni                          提供网络接口信息和名称

(2)netstat -r                            展示路由表

(3)ifconfig eth0                        获取每个接口的详细信息

(4)ping -b XXX.XXX.XXX.XXX    根据上一步找出的广播地址找出在网中的主机

十、Unix标准

      单一的Unix规范第三版有多个名称,简称为POSIX规范。它是两个长期发展的标准团体各自努力的汇合,由Austin CSRG最终团结起来。

十一、64位体系结构

      现有32位Unix系统编程模型:ILP32模型

      64位Unix系统编程模型:LP64模型

      所以必须考虑LP64对现有API的影响。(使用专门设计的数据类型)

十二、小结

      不得不说,Stevens这本书不愧是网络编程方面的扛鼎之作,覆盖面很广,而其中的代码注释又非常地详尽。其实上学期OS实验做得半死的原因也就是因为从来没有接触过OS的系统调用,其中的各种参数的使用完全是小白小白,而这里却是交代了参数的前世今生,觉得好像之前很恐怖的System Call也变得和蔼了不少。嗯,这是一个好现象,继续加油!

 

 

      

       

      

转载于:https://www.cnblogs.com/kemmyzhou/archive/2013/03/03/2892272.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值