📄 114.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 + -