【计算机网络】实验2:网络基础编程实验

【计算机网络】实验2:网络基础编程实验

一、实验目的

通过本实验,学习采用Socket(套接字)设计简单的网络数据收发程序,理解应用数据包是如何通过传输层进行传送的。

二、实验内容

  1. 采用TCP进行数据发送的简单程序

  2. 采用UDP进行数据发送的简单程序

  3. 多线程\线程池对比

  4. 写一个简单的chat程序,并能互传文件,编程语言不限。

三、实验步骤

1. 代码设计流程图

1)采用TCP进行数据发送的简单程序
【计算机网络】实验2:网络基础编程实验_第1张图片

面向连接TCP连接的套接字工作过程是:服务器首先启动,创建套接字后等待客户的连接;客户启动以后,创建套接字,然后和服务器建立连接;连接建立后,客户机和服务器可以通过建立的套接字连接进行信息通信。

2)采用UDP进行数据发送的简单程序

【计算机网络】实验2:网络基础编程实验_第2张图片

无连接UDP的套接字工作过程是:服务器首先启动,创建套接字后等待客户发来信息;客户启动以后,创建套接字,然后给服务器发送消息,客户机和服务器就可以进行信息通信了。

2. 代码解析

1)TCP & UDP的区别与联系

TCP服务是进程间可靠传输的一种方式,主要特点是:面向连接、以字节流的方式传输、点对点、全双工的方式进行。示意图如下所示:
【计算机网络】实验2:网络基础编程实验_第3张图片

UDP服务提供的是在服务器和客户端之间的不可靠传输,主要特点是:无连接、以数据报的方式传输。所以在实际编程实现当中,使用不同的传输协议TCP和UDP,所调用函数也不同。在TCP中:

【计算机网络】实验2:网络基础编程实验_第4张图片
【计算机网络】实验2:网络基础编程实验_第5张图片

【计算机网络】实验2:网络基础编程实验_第6张图片

2)代码所调用的函数

【计算机网络】实验2:网络基础编程实验_第7张图片

【计算机网络】实验2:网络基础编程实验_第8张图片

3)文件互传需要注意的问题

Q1:文件大小不确定,有可能比缓冲区大很多,调用一次write()/send() 函数不能完成文件内容的发送。接收数据时也会遇到同样的情况。

A1:要解决这个问题,可以使用 while 循环。对于 Server 端的代码,当读取到文件末尾,fread() 会返回 0,结束循环。

对于 Client 端代码,有一个关键的问题,就是文件传输完毕后让 recv() 返回 0,结束 while 循环。(注:读取完缓冲区中的数据 recv() 并不会返回 0,而是被阻塞,直到缓冲区中再次有数据。)

Q2:Client 端应该如何判断文件接收完毕?

A2:最简单的结束 while 循环的方法是文件接收完毕后让 recv() 函数返回 0,那么,如何让 recv() 返回 0 呢?recv()返回 0 的唯一时机就是收到FIN包时。FIN 包表示数据传输完毕,计算机收到 FIN 包后就知道对方不会再向自己传输数据,当调用 read()/recv() 函数时,如果缓冲区中没有数据,就会返回 0,表示读到了”socket文件的末尾“。这里我采用调用 shutdown() 的方式发送FIN包:server 端直接调用 close()/closesocket() 会使输出缓冲区中的数据失效,文件内容很有可能没有传输完毕连接就断开了,而调用 shutdown() 会等待输出缓冲区中的数据传输完毕。

四、实验结果与分析

1. 采用TCP进行数据发送的简单程序

首先运行server程序,出现”Waiting…”表示server已经成功进入监听状态,等待client的连接请求:
【计算机网络】实验2:网络基础编程实验_第9张图片

再运行client程序,server程序的运行窗口立刻出现成功建立连接的提示以及对应的client地址,还有client发送的报文,然后server又循环进入了监听状态,等待client下一个连接请求:
【计算机网络】实验2:网络基础编程实验_第10张图片

对应的client也会收到来自server的报文:

【计算机网络】实验2:网络基础编程实验_第11张图片

2. 采用UDP进行数据发送的简单程序

首先运行server程序,只出现了空白的运行窗口:

【计算机网络】实验2:网络基础编程实验_第12张图片

这是因为UDP是无连接的,这也是与TCP最大的不同点,所以在client给server发送报文之前,server不知道谁要发送报文、发送报文的内容是什么。自然不会在运行窗口显示。

再运行client程序,server程序的运行窗口立刻出现收到来自所在地址的client发送的报文,处理完成之后,server又进入了最初的空白阶段,直到还会有下一个client给他发送报文:
【计算机网络】实验2:网络基础编程实验_第13张图片

对应的client也会收到来自server的报文:

【计算机网络】实验2:网络基础编程实验_第14张图片

3. 多线程\线程池对比

1)多线程

首先运行server程序,出现为该server分配的端口号,以及出现”Waiting…”表示server已经成功进入监听状态,等待client的连接请求:

【计算机网络】实验2:网络基础编程实验_第15张图片

再运行client程序,client的运行窗口立刻出现连接成功,并提示用户输入信息:

【计算机网络】实验2:网络基础编程实验_第16张图片

同时server运行窗口发生变化,显示了与其连接的client端口号:

【计算机网络】实验2:网络基础编程实验_第17张图片

在client窗口输入要传送的报文(回车结束):
【计算机网络】实验2:网络基础编程实验_第18张图片

server运行窗口就会立刻响应有来自端口号196的client发来的消息,同时提示server构造响应报文:

【计算机网络】实验2:网络基础编程实验_第19张图片

在server运行窗口构造完响应报文(回车结束):

【计算机网络】实验2:网络基础编程实验_第20张图片

client运行窗口就会立刻响应有来自server发来的消息,同时提示client构造响应报文,又回到上述步骤开始往复进行:

【计算机网络】实验2:网络基础编程实验_第21张图片

这就实现了多线程的聊天程序,服务器可以并发地处理来自同一用户的多个请求(或者是来自不同用户的多个请求,操作类似,故不在本实验报告中展示截图步骤)。

2)线程池

在进行服务器/客户端通信之前,会出现在当前设置线程池大小(即:server在同一时间内处理client请求的线程数量)时、当前设置任务完成时间内,执行用户任务的个数。比如下图所示是线程池大小为1、完成时间为4s时仅能执行完1个任务:

【计算机网络】实验2:网络基础编程实验_第22张图片
【计算机网络】实验2:网络基础编程实验_第23张图片

下图所示是线程池大小为5、完成时间为4s时就能执行完全部3个任务:

【计算机网络】实验2:网络基础编程实验_第24张图片

这就是线程池和多线程最大的不同。线程池虽然也是单个线程处理客户的请求,但并不是每接受一个新的客户请求就新建一个线程,而是在双方开始通信之前先调用一个线程池函数(如上所示)确定了固定数量的线程,才开始惯例的通信交互。

运行server程序,出现为该server分配的端口号,以及出现”Waiting…”表示server已经成功进入监听状态,等待client的连接请求:

【计算机网络】实验2:网络基础编程实验_第25张图片

再运行client程序,client的运行窗口立刻出现连接成功,并提示用户输入信息:

同时server运行窗口发生变化,显示了与其连接的client端口号:

【计算机网络】实验2:网络基础编程实验_第26张图片
在client窗口输入要传送的报文(回车结束):
【计算机网络】实验2:网络基础编程实验_第27张图片

server运行窗口就会立刻响应有来自端口号196的client发来的消息,同时提示server构造响应报文:
【计算机网络】实验2:网络基础编程实验_第28张图片

在server运行窗口构造完响应报文(回车结束):

【计算机网络】实验2:网络基础编程实验_第29张图片

client运行窗口就会立刻响应有来自server发来的消息,同时提示client构造响应报文,又回到上述步骤开始往复进行:

【计算机网络】实验2:网络基础编程实验_第30张图片

4. 互传文件的聊天程序

首先把server程序和client程序分别放在两个不同路径下的文件夹内,server程序所在 的文件夹内还有一个待传送的文件:
【计算机网络】实验2:网络基础编程实验_第31张图片

client程序所在的文件夹内则没有这个文件:

【计算机网络】实验2:网络基础编程实验_第32张图片

运行server程序,出现提示表明server已经成功进入监听状态,等待client的连接请求:
【计算机网络】实验2:网络基础编程实验_第33张图片

再运行client程序,client的运行窗口立刻提示用户输入想要的文件名:

【计算机网络】实验2:网络基础编程实验_第34张图片

在client的运行窗口输入要传输的文件名(本例中为test.cpp),回车键结束后提示已传输成功:

【计算机网络】实验2:网络基础编程实验_第35张图片

server运行窗口就会立刻显示该文件已传输成功,并跳转循环回第一个步骤等待处理客户的下一个请求:

【计算机网络】实验2:网络基础编程实验_第36张图片
于是在client程序所在的文件夹内就能看到test.cpp文件了:

【计算机网络】实验2:网络基础编程实验_第37张图片

五、实验心得

通过本次实验“网络基础编程”,我掌握了Wireshark的使用方法,能熟练运用Wireshark捕获报文并对捕获到的数据分组进行分析,对照课本知识分析HTTP 协议的报文格式,并了解了HTTP 协议的工作过程。整个实验难度系数不算高,但我还是遇到了一些困难。比如一开始捕获报文时,由于对Wireshark操作不熟练,没有对所有捕获的报文进行条件筛选,这时很难查看HTTP协议的报文以及分析HTTP的报文格式。通过独立完成本次实验,我学会了将课本上的知识学以致用,掌握了许多新知识。

你可能感兴趣的:(网络,网络通信,网络协议)