网络工程期末作业.docx

上传人:b****1 文档编号:23074583 上传时间:2023-04-30 格式:DOCX 页数:34 大小:420.81KB
下载 相关 举报
网络工程期末作业.docx_第1页
第1页 / 共34页
网络工程期末作业.docx_第2页
第2页 / 共34页
网络工程期末作业.docx_第3页
第3页 / 共34页
网络工程期末作业.docx_第4页
第4页 / 共34页
网络工程期末作业.docx_第5页
第5页 / 共34页
点击查看更多>>
下载资源
资源描述

网络工程期末作业.docx

《网络工程期末作业.docx》由会员分享,可在线阅读,更多相关《网络工程期末作业.docx(34页珍藏版)》请在冰豆网上搜索。

网络工程期末作业.docx

网络工程期末作业

基于TCP的WinSock网络编程

班级:

11计科

(1)班姓名:

冯晓凤学号:

2011329620102

1、概念介绍

1.socket

socket通常称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。

在Internet上的主机一般运行了多个服务软件,同时提供几种服务。

每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

2.TCP协议

TCP(TransmissionControlProtocol,传输控制协议)是一种面向连接的可靠的传输协议,在端点与端点之间建立持续的连接而进行通信。

建立连接后,发送端将发送的数据印记了序列号和错误检测代码,并以字节流的方式发送出去;接收端则对数据进行错误检查并按序列顺序将数据整理好,数据在需要时可以重新发送,因此整个字节流到达接收端时完好无缺。

这与两个人打电话的情形是相似的,两方先建立连接,先输出的话先到达。

TCP协议具有可靠性和有序性,并且以字节流的方式发送数据,它通常被称为流通信协议。

3.Socket通信

Socket编程是利用TCP协议在客户和服务器之间建立一个专门的点到点的通信连接技术来实现数据交换。

Socket通信就是利用TCP协议进行通信,需要编写服务器端和客户端两个程序,一般的通信过程如下:

首先服务器端和客户端都创建各自的Socket类,然后服务器开始监听某个端口是否有连接请求,客户端向服务器端发出连接请求,服务器端向客户端发回接收消息,一个Socket连接就建立起来了;服务器端和客户端都可以打开连接到Socket的输入输出流,按照一定的协议对Socket进行读/写操作与对方通信;通信结束,Socket完毕。

二、编程内容:

使用网络编程语言(C++)编写一个简化的、类似FTP文件传输服务的client/server应用,client和server之间的通信基于TCP协议,client从用户接收命令,然后与server进行交互。

三、设计思路

1、分别设计客户端和服务器程序,具有可视化界面,并且可以实现多种格式的文件传输。

2、客户端:

(网络功能使用非阻塞模式,即消息响应模式)

功能:

  client创建一个TCPsocket并连接到server。

然后等待用户输入3种命令:

dir,get和exit。

如果用户输入的不是这三种命令,则提示用户输入错误。

如果用户输入了合法的命令,client将命令发送给server。

如果是“dir”或者“get”命令,则必须从server读取响应结果。

Client应该首先读取server返回的状态码,并在屏幕输出该命令是否成功的信息,然后显示server返回的其他内容(即状态行以后的所有信息)。

对于“get”命令提供所要下载文件的存放路径,将从服务器接收的文件保存在所设的路径下。

执行完一个命令后,Client等待用户的下一次输入。

如果是“exit”命令,client将exit命令发送给server,然后关闭socket并退出。

过程:

1、在vc++6.0中,建立一个基于对话框的工程,创建过程中将所要包含的特点的windowssockets选项选中。

2、定义一个CAsyncSocket类,命名为clientsocketchen,在该类中定义对话框类变量CDialog*m_hand,构建虚函数OnClose、OnConnect、OnReceive、OnSend,自建函数

  voidclientsocketchen:

:

SetParenet(CDialog*p)

  {//将对话框类的函数的访问入口传给clientsocketchen

  m_hand=p;

  },

在构建的虚函数中,每段做相似的处理,在该消息处理不成功的时候,反复调用该函数:

voidclientsocketchen:

:

OnClose(intnErrorCode)

  {

//如果clientsocketchen的OnClose不成功,则再次调用CClientchenDlg的OnClose()函数

if(nErrorCode==0)

((CClientchenDlg*)m_hand)->OnClose();

CAsyncSocket:

:

OnClose(nErrorCode);

  }。

3.对话框类的设计:

如上图示,拖放和设置各控件,设置文本框相应变量:

CListBoxm_msg;//存放客户端信息和从服务器返回的信息

intm_port;//指定与服务器相同的端口

CStringm_ip;//服务器的ip地址

CStringm_order;//命令输入窗口的相应变量

CStringm_path;//存放下载的文件的路径并为文件命名

设置控件按钮事件函数:

voidOnReadme();//版本说明函数

voidOnbuttonSend();//命令发送按钮消息

voidOnBreak();//断开连接函数

voidOnBconnet();//连接按钮消息

voidOnSave();//保存文件路径函数,调用文件浏览对话框

voidOnshuoming();//弹出说明文档的按钮消息

界面设计完毕之后,设置与clientsocketchen对应的消息函数入口:

voidOnReceive();//接收服务器的返回信息并做相应处理

voidOnConnect();//与服务器连接上时的相应信息

voidOnSend();//发送客户端命令

voidOnClose();//关闭客户端socket

并设计相关的全局变量:

CFilefile;//用于存放下载的文件

inti;//用于存放正在接收的文件的进度

inttype;//用于标识命令的类型

intdataLength;//接收文件时每次接收到数据包的大小

CStringss;//用于将接收到的服务器返回的"200OK"和文件长度

byte*data;//存放接受文件时每次接收到的数据包

下面对关键的文件命令解析与处理做相应的解释:

命令的发送:

a.对于dir、exit命令,只需在文件命令编辑框中键入所需的命令,按下发送按钮即可,程序会调用相应的OnbuttonSend函数,由该函数指向OnSend函数。

b.对于get命令,必须在该命令调用前指定所要下载的文件的保存路径,在保存路径编辑框中键入所要保存的路径,或者单击“浏览”按钮->OnSave函数,调用文件路径选择对话框,选择要保存的路径及相应的文件名。

此处代码不做赘述,详见源代码及相应注释。

然后再调用OnbuttonSend->OnSend,对命令作相应的处理。

c.在OnSend中,对输入的命令进行判别,给每个种类的命令赋予一个标识符,存放在变量type中,其中

exit->type=0;

get—>type=1;

dir—>type=2;

else—>type=5;//即错误命令则type=5,同时将命令发送给服务器。

命令的接收:

当服务器有消息发出时,客户端响应函数OnReceive,对自服务器接收到的消息做相应的处理:

a.判断之前发出的命令属于哪种命令,用type作为判断的依据。

b.当type=0,即命令为“exit”,关闭服务器,关闭服务器对话框窗口退出。

c.当type=2,即命令为“dir”,在连接信息窗口中,显示每一条返回的文件路径。

d.当type=1,即命令为“get文件名”,首先接收返回的服务器信息,此条信息显示是否存在所要下载的文件。

若文件存在则令type=3,并且在服务器发送来下次信息时触发OnReceive函数,转入type=3分支。

e.在type=3分支中,接收服务器发来的关于文件长度的信息,并显示在连接信息窗口中,初始化接收文件所要用到暂存变量data,文件位置指示值i=0,令type=4,并且将存放要下载的文件内容的事先创建好的文件打开。

f.在type=4分支中,将文件分为1024字节的数据块进行接收,接收到的文件数据块存放在data中。

g.当type=5,为发送了错误命令时的处理操作。

接收服务器返回的错误命令信息"400Commanderror",并显示在连接信息窗口中。

在OnInitDialog函数中,

clientchen.SetParenet(this);//将当前的对话框类的函数的访问入口传给其它函数

主要的逻辑框图

由于采用事件响应方式,诸如弹出说明文档窗口等按钮事件响应函数与程序主要功能是相对独立的,因而在逻辑框图中未加以表示。

另外,OnSend,OnReceive函数详细的处理步骤已在前面详细描述,因此在流程图中不加以说明。

3、服务器:

(网络功能使用非阻塞模式,即消息响应模式)

功能:

server创建一个TCP监听socket并等待client的连接,一旦有client连接,它接受client发送的三种命令:

dir、get和exit。

●如果server接收到dir命令,它首先返回一行“200OK”,然后返回可以发送给client的所有文件名称。

●如果server接收到exit命令,它关闭所有打开的socket,然后退出。

●如果server接收到get命令,这里是client请求server传送的文件名称,如果有此文件,server首先返回一行“200OK”,然后将该文件的内容返回,这里是文件的长度。

●如果server接收到任何其他命令,则返回“400Commanderror”。

●如果client请求的文件不存在,则返回“404Filedoesnotexist”。

1.在vc++6.0中,建立一个基于对话框的工程,创建过程中将所要包含的特点的windowssockets选项选中。

2.定义一个CAsyncSocket类,命名为chenserversocket,在该类中定义对话框类变量CDialog*hand,构建虚函数OnClose、OnAccept、OnReceive、OnSend,自建函数

  voidchenserversocket:

:

sethand(CDialog*p)

  {//将对话框类的函数的访问入口传给chenserversocket

hand=p;

}

在构建的虚函数中,每段做相似的处理,在该消息处理不成功的时候,反复调用该函数:

  voidchenserversocket:

:

OnAccept(intnErrorCode)

  {

//如果chenserversocket的OnAccept不成功,则再次调用//CServerchenDlg的OnAccept()函数

  if(nErrorCode==0)

  ((CServerchenDlg*)hand)->OnAccept();

  CAsyncSocket:

:

OnAccept(nErrorCode);

  }

3.对话框类的设计:

如上图示,拖放和设置各控件,设置文本框相应变量:

CListBoxm_msg;//存放反馈信息

intm_port;//存放所选的端口号

CStringm_path;//存放发送过来的要下载的文件名

设置控件按钮事件函数:

voidOnReadme();//版本信息说明(按钮消息控件)

voidOnStart();//启动服务器(按钮消息控件)

voidOnLook();//选择供下载的文件目录(按钮消息控件)

voidOnBreak();//断开连接(按钮消息控件)

voidOnshuoming();//使用说明

界面设计完毕之后,设置与chenserversocket对应的消息函数入口:

voidOnSend();//根据接收到的客户端命令类型返回服务器信息的相应处理函数

voidOnReceive();//接收来自客户端的命令消息

voidOnAccept();//响应客户端的连接请求消息之后作出相应的处理

voidOnClose();//关闭服务器的socket

自建查找指定目录下的文件路径并返回给客户端的函数:

voidfilefinder(CStringx);//x为指定的目录并设计相关的全局变量

CStringfilename;

inttime;//用于传送文件失败时设置重试的次数

inttype;//用于判断接收到的命令的类型

intready;//可以开始发送的标志

chary[256];//存放供下载的当前目录

下面就服务器接收到客户端的命令之后作出响应的具体处理过程进行阐述:

当客户端发送来消息时,响应OnReceive函数:

a.接受来自客户端的消息内容,存放在字符串指针pb中

b.将pb的值传给CString变量s,并令变量标识值type=3

c.用if语句进行判断,在s中寻找命令关键字。

if(s.Find("dir")!

=-1){//若为dir命令

type=0;

this->m_msg.ResetContent();//清空CListBox控件内容

}

elseif(s.Find("get")!

=-1){//若为get命令

type=1;

s.Delete(0,4);//提取文件名

filename=s;

this->m_msg.ResetContent();//清空CListBox控件内容

}

elseif(s.Find("exit")!

=-1){//若为exit命令

type=2;//设命令类型为2

}

d.在服务器信息窗口中显示接收到的命令,并令ready=1,表示允许响应OnSend函数中的内容,并调用OnSend函数。

OnSend函数:

type=2,type=3的流程图:

文件目录返回函数filefinder(CStringx)流程图:

在OnInitDialog函数中,

serversocket.sethand(this);//将当前的对话框类的函数的访问入口传chenserversocket

chenconnectsocket.sethand(this);//将当前的对话框类的函数的访问入口传chenserversocket

在OnLook函数中,除了弹出文件目录对话框选择可供下载的文件目录外,使用getcwd(y,256),得到当前所在目录,便于之后在文件查找命令中的应用。

主要的逻辑框图

由于采用事件响应方式,诸如弹出说明文档窗口等按钮事件响应函数与程序主要功能是相对独立的,因而在逻辑框图中未加以表示。

4、实验主要代码

1.客户端的主要代码:

OnSend函数:

voidCClientchenDlg:

:

OnSend(){

UpdateData(true);

if(this->m_order!

=""){//当有命令输入时

if(clientchen.Send(this->m_order,m_order.GetLength())==SOCKET_ERROR){

this->m_msg.AddString("发送命令失败");

UpdateData(false);

}

else{//设置命令标识类型

if(this->m_order=="exit"){

type=0;

}

elseif(this->m_order.Find("get")!

=-1){

type=1;

this->m_msg.ResetContent();//清空CListbox控件的显示内容

}

elseif(this->m_order=="dir"){

type=2;

this->m_msg.ResetContent();//清空CListbox控件的显示内容

}

else

type=5;//输入的是错误命令

this->m_msg.AddString("成功发送命令"+this->m_order);

UpdateData(false);

}

}

}

OnReceive函数:

voidCClientchenDlg:

:

OnReceive(){//对服务器返回的信息作相应的处理

CStrings;

this->UpdateData(true);

if(type==0){//若为"exit"命令

intbsize=1024;

char*pb=newchar[1024];

intirev=clientchen.Receive(pb,bsize);//接收服务器的关闭信息

if(irev==SOCKET_ERROR){

this->m_msg.AddString("接收失败");

this->UpdateData(false);

}

else{

pb[irev]=NULL;

s=pb;

this->m_msg.AddString(s);

this->UpdateData(false);

clientchen.Close();

this->DestroyWindow();//关闭客户端窗口

}

}

if(type==2){//若为dir命令

intbsize=1024;

char*pb=newchar[1024];

intirev=clientchen.Receive(pb,bsize);

if(irev==SOCKET_ERROR){

this->m_msg.AddString("接收失败");

this->UpdateData(false);

}

else{

pb[irev]=NULL;

s=pb;

this->m_msg.AddString(s);//在客户端的信息窗口中显示返回的每一条文件路径

this->UpdateData(false);

}

}

if(type==4){//开始接收文件数据

if(i<=dataLength){//当文件仍在接收进程中时

intirev=clientchen.Receive(data,1024);//接收文件数据

if(irev==SOCKET_ERROR){

this->m_msg.AddString("接收数据失败");

this->UpdateData(false);

}

else{

this->m_msg.AddString("成功接收数据");

this->UpdateData(false);

s="已重试一百次,文件传送失败";

if(data==s){//文件传送失败,中止接收

this->m_msg.AddString(s);

this->UpdateData(FALSE);

file.Close();

file.Remove(this->m_path);//移除未接收完文件

}

else{

i+=1024;//文件数据接收成功,指示位置向后移动1024字节

file.Write(data,irev);//写入实际接收到的数据,大小为实际数据包的大小

file.SeekToEnd();//将文件指针指向文件结尾处,便于下个数

//据包的接收

}

}

}

if(i>dataLength)//接收完毕

{

file.Close();

this->m_msg.ResetContent();//清空客户端信息窗口

this->m_msg.AddString(ss);//重新按要求显示文件长度

this->m_msg.AddString("文件接收完毕,已保存至");

this->m_msg.AddString(this->m_path);

this->UpdateData(false);

}

}

if(type==3){//返回文件长度信息时

char*temp=newchar[1024];

dataLength=0;

intirev=clientchen.Receive(&dataLength,4);//接收文件长度

if(irev==SOCKET_ERROR){

this->m_msg.AddString("接收失败文件长度");

this->UpdateData(false);

}

else{

itoa(dataLength,temp,10);//转化为字符串,便于在客户端信息窗口中输出

ss+=temp;//将服务器分开发送过来的"200ok"和文件长度合成一条信息显示

this->m_msg.AddString(ss);

this->UpdateData(false);

data=newbyte[1024];

//打开文件,准备往文件里写数据

file.Open(this->m_path,CFile:

:

modeCreate|CFile:

:

modeReadWrite|CFile:

:

typeBinary);type=4;//开始发送文件数据时转入type=4分支

i=0;//初始化文件位置指示值为0

}

}

if(type==1){//为"get"命令

intbsize=1024;

char*pb=newchar[1024];

intirev=clientchen.Receive(pb,bsize);

if(irev==SOCKET_ERROR){

this->m_msg.AddString("接收失败");

this->UpdateData(false);

}

else{

pb[irev]=NULL;

s=pb;

this->UpdateData(false);

if(s!

="404Filedoesnotexist"){//找到文件,返回信息为"200ok"

type=3;//将命令类型设为3,便于下次接收到服务器信息时转入type=3分支

ss=s;/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1