第3讲TCP客户端服务器程序示例FTP服务器和客户机Word文件下载.doc
- 文档编号:13316950
- 上传时间:2022-10-09
- 格式:DOC
- 页数:8
- 大小:459KB
第3讲TCP客户端服务器程序示例FTP服务器和客户机Word文件下载.doc
《第3讲TCP客户端服务器程序示例FTP服务器和客户机Word文件下载.doc》由会员分享,可在线阅读,更多相关《第3讲TCP客户端服务器程序示例FTP服务器和客户机Word文件下载.doc(8页珍藏版)》请在冰豆网上搜索。
3.4发送指定字节函数write_all
4服务器程序分析
4.1程序流程(见右图)
4.2主要模块分析
l初始化模块
getservbyname
l读取客户端请求模块
read_line函数
read_all函数
l处理客户端请求
l返回服务器响应
write_all函数
5客户端程序分析
5.1程序流程(见右图)
5.2主要模块分析
命令行参数(服务器IP,端口)
l读取用户输入
ftp命令及命令参数获取(gets函数)
l发送请求给服务器
分别发送命令长度和命令及参数
l读取服务器响应
read_line函数、read_all函数
6程序运行状况分析(使用netstat命令查看socket状态,采用一些程序调试手段)
6.1正常运行状况
l在一个终端启动服务器程序(命令行:
./ftpserver)
显示提示信息,服务器在函数调用accept处阻塞,服务器socket状态为LISTEN
l在另一终端启动客户端程序(命令行:
./ftpclient127.0.0.121)
显示提示信息,服务器socket状态为LISTEN,新生成的连接socket状态为ESTABLISHED,客户端socket状态为ESTABLISHED
l客户端和服务器进行一次通信,过程如下
(1)客户端调用函数gets从控制台读取用户输入
(2)客户端调用write_all函数发送命令长度
(3)客户端调用write_all函数发送命令内容
(4)服务器调用read_line函数读取命令长度
(5)服务器调用read_all函数读取命令内容
(6)服务器处理客户端请求得到响应结果
(7)服务器调用write_all函数发送响应长度
(8)服务器调用write_all函数发送响应内容
(9)客户端调用read_line函数读取响应长度
(10)客户端调用read_all函数读取响应内容
通信过程中的这10个步骤是并行的,没有严格的顺序
l结束通信过程(客户端主动关闭)
(1)客户端通过控制台键入CTRL+D,使gets函数返回NULL,结束cli_requ函数调用,客户端主函数调用close关闭客户端socket,进入FIN_WAIT1状态
(2)服务器的socket在接收完数据后返回对客户端的FIN字段的确认,进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态,为了查看这两个状态需要使服务器在调用close函数前暂停(加入getchar函数)
(3)服务器收到客户端的FIN字段时正阻塞在read_line函数的调用过程中,read_line函数将返回0,使得read_requ函数结束,serv_resp函数结束
(4)函数serv_resp结束后,服务器主程序调用函数close关闭socket,服务器发送FIN字段进入LAST_ACK状态,(当网络速度较慢时可以查看到这个状态)客户端TCP协议收到服务器FIN字段之后进入TIME_WAIT状态,并返回对FIN字段的确认,超时后删除客户端socket
(5)服务器继续侦听其他连接请求,处于LISTEN状态
6.2服务器主动关闭连接
为了模拟服务器主动关闭连接,我们在服务器read_requ函数之后加入return语句,函数serv_resp立即返回主程序,调用close函数关闭socket,TCP协议向客户端发送FIN数据段,客户端TCP协议收到FIN数据段后返回确认,进入CLOSE_WAIT状态,服务器进入FIN_WAIT2状态。
客户端在发送完请求后阻塞在函数read_resp中,收到FIN字段将返回主函数,调用函数close关闭socket,TCP协议向服务器发送FIN数据段,服务器确认该数据段进入TIME_WAIT状态。
6.3服务器进程终止
ps–a 得到服务器的进程id
killid 终止服务器进程
l终止服务器进程时没有客户端连接
终止进程,关闭socket
l终止服务器进程时有未完成的客户端连接
服务器终止进程,关闭socket
(1)如果客户端已经收到SYNACK,connect函数成功,接下来向socket写数据时将失败
(2)服务器尚未确认客户端SYN,或SYNACK丢失,connect函数失败
l终止服务器进程时已有客户端建立连接
服务器进程终止,TCP协议向客户端发送FIN数据段,为了模拟客户端在不同时刻收到FIN数据段,在客户端程序3个地方加入getchar暂停程序
(1)客户端在调用第一个write_all函数前收到FIN数据段,认为服务器不再发送数据,但write_all函数成功,数据到达服务器后,服务器将向客户端发送RST数据段,客户端在调用第二个write_all函数时将被SIGPIPE信号中断,显示BrokenPipe
(2)客户端在调用第二个write_all函数前收到FIN数据段,认为服务器不再发送数据,但write_all函数成功,数据到达服务器后,服务器将向客户端发送RST数据段,此时如果在RSt字段没有到达客户端之前调用函数read_resp,由于已经收到FIN字段,read_resp函数将返回0;
如果客户端已经收到RST数据段,则返回CONNREST
(3)客户端在调用read_resp函数前收到FIN数据段,read_resp函数返回0
6.4服务器主机崩溃
由于服务器主机复位,或断线会造成这种情况,主机崩溃和进程终止不同,系统不会关闭进程拥有的socket
l客户端在等待服务器数据时服务器主机崩溃
调用read_resp函数过程中服务器主机崩溃,客户端将永远阻塞,除非设置了读超时选项
l客户端向服务器发送数据时服务器主机崩溃
(1)write_all函数成功执行(拷贝到系统缓冲区),read_all函数阻塞,直到TCP协议重发数据达到限制次数后,返回错误ETIMEOUT
(2)当发送数据需要经过路由器时,路由器会发现服务器主机不可达,向客户端返回ICMP消息,函数调用read_all返回错误EHOSTUNREACH。
6.5客户端主机崩溃(类似于服务器主机崩溃)
l服务器接收客户端请求时客户端主机崩溃
服务器的read_requ函数将永远阻塞,由于服务器是循环服务器,因此服务器永远阻塞,导致服务失效,可以采用并发服务器避免
l服务器向客户端返回响应时客户端主机崩溃
write_all函数成功执行(拷贝到系统缓冲区),read_all函数阻塞,直到TCP协议重发数据达到限制次数后,返回错误ETIMEOUT
补充知识:
多源文件程序编译
1.分别编译各个源文件,利用生成的中间文件(后缀为.o)生成可执行程序
gcc–cftpclient.c
gcc–ccomm_func.c
gcc–oftpclientftpclient.ocomm_func.o
2.生成makefile,利用make整体编译
make命令:
make–fmakefile
makefile中最重要的是描述文件的依赖关系,一般格式为
target:
componets 依赖关系
TABrule 规则(TAB不能省略)
l第一种makefile(内容较多,容易理解)
#ftpclientmakefile 注释
ftpclient:
ftpclient.ocomm_func.o
gcc-oftpclientftpclient.ocomm_func.o
#以下为各个组成元素的子元素及生成方法
ftpclient.o:
ftpclient.ccomm_func.h
gcc-cftpclient.c
comm_func.o:
comm_func.ccomm_func.h
gcc-ccomm_func.c
l第二种makefile
$@--目标文件,$^--所有的依赖文件,$<
--第一个依赖文件
#ftpclientmakefile
ftpclient.ocomm_func.o
gcc-o$@$^
gcc-c$<
l第三种makefile
.c.o规则,表示所有的.o文件依赖于对应的.c文件(文件名相同)
.c.o:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TCP 客户端 服务器 程序 示例 FTP 客户机