⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 114.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="55.htm">上一层</a>][<a href="115.htm">下一篇</a>]
<hr><p align="left"><small>发信人: lookout (看世界), 信区: UNP <br>

标  题: UNP第一章学习之标准课堂笔记篇 <br>

发信站: UNIX编程 (2001年10月13日11:04:01 星期六), 站内信件 <br>

  <br>

//好不容易发了些工资,才可以拿回UNP两卷,可以有空时学习啦 <br>

  <br>

〖课前预习]: <br>

先回想一下对网络编程的一些感受,在我来说就是C/S型的程序。 <br>

套用beej的比喻,相当于打电话者与接电话者之间的交互。下面以 <br>

TCP连接过程(双方只有一台电话可用?)来表达我的理解: <br>

  <br>

          客户端                                服务端 <br>

     找一台可用的电话<----socket()------>申请一台可用的电话 <br>

                           bind()-------->把申请到的号码绑定到一根电话线上 <br>

     拨打服务端电话号<---connect() <br>

                           listen()------>等待客户端的电话 <br>

                           accept()------>接到客户端的电话,拿起话筒 <br>

     向对方说出自己的话<----send()------>向对方说出自己的话 <br>

     听对方向自己说的话<----recv()------>听对方向自己说的话 <br>

           挂断电话 <-------close()--------->挂断电话 <br>

  <br>

一个典型的C/S程序交互过程是类型似以上的过程罢 <br>

  <br>

  <br>

〔课堂学习〕: <br>

UNP第一章是给出一个完整的C/S程序组的Client端和Server端程序,对于 <br>

刚开始初学的人很有帮助。 <br>

先看客户端程序daytimetcpcli.c((请参看书上的源程序) <br>

以下为编写一个客户端程序时的思路顺序: <br>

  <br>

1 确定要用到的参数 <br>

int sockdf    ----->整型的套接字文件标识符 <br>

(我想提醒的是:最好在看到书中的某个变量时,应能立即知道它应该是什么 <br>

类型的变量,其名字有什么含义。如sockdf == socket file descriptor ,类型 <br>

是int, 这样我看到这一行时,会默默地念"int类型的socket[套接字]file[文件] <br>

descriptor[描述符],以下变量我也将以这种方式做为我的思路记录) <br>

char recvline[MAXLINE+1] ---->char类型的receive[接收数据]line[记录行]变量, <br>

                              它是个数组,是保存网络传来的字符数据用的。 <br>

struct sockaddr_in servaddr   --->网际套字节流套接字结构变量。其含义为 <br>

                               server address变量(服务器端地址)是一个socket <br>

                               address of internet类型的结构体变量,这个结构 <br>

                              体包含了象网络地址,端口,传输协议等结构体成员。 <br>

                              相当于服务器端电话的号码、线路、、脉冲或数字信号 <br>

                              传送之类的。 <br>

  <br>

2 实现过程 <br>

2 实现过程 <br>

(1)创建可用的网际套接口(找到一台可用的电话) <br>

sockfd=socket(AF_INET,SOCK_STREAM,0); <br>

用socket()函数来找到一个可用的接口,其中的参数分别是:AF_INET  == Address <br>

Family_InternetNET(注意把相应的缩写变为忆记的单词)是地址族协议,一般选用 <br>

InternetNET类型;SOCK_STREAM == SOCKET_STREAM是常量,表示用字节流形式的套接 <br>

口;最后的参数应该是传输协议的指定,用0表示让内核自动为我们选择相应的协议, <br>

这样又快又对,何乐而不为? <br>

注意一般要对函数调用结果进行检查,以防止出现意外错误。 <br>

  <br>

(2)向该套接口填写特定的信息(确定服务端电话的信息) <br>

<1>清空该套接口结构变量,象我打电话前喜欢先确定挂断。 <br>

bzero(&servaddr,sizeof(servaddr)); <br>

      ~~|-->载体 ~~~~|--->长度 <br>

  <br>

<2>选定地址族协议,相当于检查电话是处于脉冲或音频状况 <br>

servaddr.sin_family=AF_INET; <br>

结构体成员sin_family == socket internet_family,地址族协议选用AF_INET. <br>

而AF_INET == AddressFamily_InternetNET. <br>

  <br>

<3>选定端口,相当于检查电话是不是连接电话线上了 <br>

servaddr.sin_port=htons(13); <br>

同理,sin_port == socket internet_port.端口号。为什么使用htons()函数?因为 <br>



在网络上传输数据要求大家遵守同样的数据字节顺序,否则你用从左向右读的字节 <br>

数据,我用从右向左的字节顺序,就不能正确的交换数据。而htons == host to network <br>

short(机器到网络字节顺序的short类型),它能保证你送出的数据被网络上的其它主 <br>

机正确接收、处理。 <br>

  <br>

<4>选定服务器端IP地址,即找到服务端的电话话码 <br>

inet_pton(AF_INET,argv[1],&servaddr.sin_addr); <br>

这个inet_pton()函数把表达式(ASCII码字符)变为网络其它主机可正确接收和处理的 <br>

字节顺序字符串,即inet_pton == internet_p(???) to network.其第一个参数是地址族 <br>

协议;第二个参数是IP地址表达式,argv[1]是C语言中的命令行参数选项数组中的第 <br>

二个元素,如daytimetcpcli 192.168.0.1这个命令中的 argv[1]就是192.168.0.1,我 <br>

们应该把它变为网络上可用的字符串,才能把它向网络送出,否则别人无法识别你 <br>

的信息。 <br>

在beej的教程中,提到可用简单的 <br>

servaddr.sin_addr=inet_addr(argv[1])来实现上述要求。 <br>

  <br>

(3)建立与服务器的连接,即开始拨打服务端的电话 <br>

connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); <br>

请回忆sockfd == ????????. 用connect()得到可用的与服务器端相通的数据传送管道, <br>

这个管道表现为sockfd这个文件标识符,送入该“文件”中的数据流向远程服务器端, <br>

从该“文件”读出的数据即远程服务器送平的数据。 <br>

  <br>

  <br>

(4)建立与远程服务器通信的循环,即不断地与对方通信、交流 <br>

对这个过程,我以伪代码形式来理解。 <br>

当从套接口文件标识符(sockfd)中读数据(将其存放于recvline[]中)不出错时 <br>

     循环 做以下事情: <br>

     ==1==    给接收到的数据加上结束符号 <br>

     ==2==    向控制台输出接收到的数据 <br>

  <br>

(5)结束与服务器端的通讯(电话挂断了) <br>

对客户端来说,一般都是等待服务器端主动结束通讯。象打电话一样,一般对方想结束 <br>

通话时,我们才会say byebye.在这里,结束通讯可能是服务器端正常主动结束,或者是 <br>

意外出错中断。可以用接收到的字节数目来判断: <br>

n == 0   ---------->服务器端正常主动结束通讯 <br>

n <  0   ---------->意外出错中断,应该给出警告 <br>

当收到结束的要求时(不论是正常或意外),客户端都退出连接程序,完成自己的使命。 <br>

用close()来正常退出程序。 <br>

  <br>

[休息一下,下半堂课学习服务器端程序的编写,happy] <br>

  <br>

[叮铃铃....开始上课了*_^] <br>

  <br>

以下为编写一个服务器端程序的思路: <br>

  <br>

  <br>

1 确定要使用的参数 <br>

  <br>

int listenfd,connfd;   //很明显,listen[监听]file descriptor和connect[连接] <br>

                       //file descriptor是两个用于数据通讯的文件标识符 <br>

struct sockaddr_in servaddr; //服务器端信息结构体变量,存放相关信息 <br>

char buffer[MAXLINE];    //buff == buffer[缓冲区],暂时存放相关数据字符串 <br>

time_t ticks;            //ticks意为时钟的嘀哒声,这是Unix下计算时间常用的方法 <br>

  <br>

2 服务器工作设计 <br>

  象我们公司要找一个给老板做秘书,专职处理给老板的电话一样。我们的服务器 <br>

程序也可以仿现实中的工作来设计。先看看秘书是如何工作的(sorry,亲爱的秘书小姐, <br>

我只是描述方便,并没有对你有非份之想哦:-),她要守在电话机旁,当有电话打入时, <br>

她立即拿起话筒,与对方通讯,了解对方的意图,然后给对方提供相关信息或记录 <br>

对方提供的信息,然后say byebye,等待下一个电话的到来。 <br>

  ok,我们的服务器程序也是这样工作的。 <br>

  <br>

3 实现过程 <br>

(1)创建可用的套接口(申请开通一个电话,最好取消初装费哦) <br>

listenfd=socket(AF_INET,SOCK_STREAM,0); <br>

参看客户端程序中的说明,一样的道理。 <br>

  <br>

(2)填写服务器端相关的信息(把电话机连到电话线上,设定脉冲工作方式,确定响 <br>



铃是否正常工作) <br>

<1>bzero(&servaddr,sizeof(servaddr)); //挂断一次,确保前面谈话中断 <br>

<2>servaddr.sin_family=AF_INET;       //传输协议类型确定 <br>

<3>servaddr.sin_port=htons(13);       //电话机连接到电话线了 <br>

<4>servaddr.sin_sin_addr.s_addr=htonl(INADDR_ANY);   //可在任意类型接口上连接 <br>

  <br>

(3)服务器地址、监听端口绑定(确定哪台电话是秘书小姐要接听的) <br>

Bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); //就是listenfd <br>

                                                              //这台电话要接听 <br>

  <br>

(4)建立监听进程(开始正式上班啦) <br>

Listen(listenfd,LISENQ);    //LISENQ == 1024, 每次监听的最大允许数 <br>

  <br>

(5)等待客户端的到来(等有电话打进来,我想她一定希望天天有空上QQ:-) <br>

用一个死循环来实现,伪代码如下: <br>

    一直循环做以下事情: <br>

        I. 为每个新到连接创建可用的套接口文件标识符(拿起话筒accept()函数) <br>

        II.取得当前时间(难道会有人打电话问公司现在是多少时间??) <br>

        III.将取得的时间转为普通用户可识别的字符串(看表,记录时间) <br>

        IV.把时间字符串写到套接口文件标识中(送往客户端)(用甜甜的声音告诉对方) <br>

        V. 主动结束与客户的通讯(挂断电话) <br>

  <br>



以上为一个服务器端程序编写的过程,不知我这样的类比是否能让你对我的思路更 <br>

了解。如有错误之处,请一定告诉我。 <br>

  <br>

  <br>

  <br>

  <br>

  <br>

  <br>

-- <br>

※ 修改:·lookout 於 10月13日11:56:39 修改本文·[FROM: 202.114.1.121] <br>

※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.1.121] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="55.htm">上一层</a>][<a href="115.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -