东南大学计算机网络第三次实验报告.docx

上传人:b****5 文档编号:8005704 上传时间:2023-01-27 格式:DOCX 页数:15 大小:1.05MB
下载 相关 举报
东南大学计算机网络第三次实验报告.docx_第1页
第1页 / 共15页
东南大学计算机网络第三次实验报告.docx_第2页
第2页 / 共15页
东南大学计算机网络第三次实验报告.docx_第3页
第3页 / 共15页
东南大学计算机网络第三次实验报告.docx_第4页
第4页 / 共15页
东南大学计算机网络第三次实验报告.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

东南大学计算机网络第三次实验报告.docx

《东南大学计算机网络第三次实验报告.docx》由会员分享,可在线阅读,更多相关《东南大学计算机网络第三次实验报告.docx(15页珍藏版)》请在冰豆网上搜索。

东南大学计算机网络第三次实验报告.docx

东南大学计算机网络第三次实验报告

东南大学自动化学院

实验报告

 

课程名称:

信息通信网络概论

 

第3次实验

 

实验名称:

实验三基于客户/服务器模式的网络通信编程实现

院(系):

自动化专业:

自动化

姓名:

学号:

实验室:

金智楼实验组别:

同组人员:

实验时间:

2016年12月13日

评定成绩:

审阅教师:

一.实验目的和要求·····································3

二.实验原理···········································3

三.实验方案与实验步骤·································4

四.实验设备与器材配置·································5

五.实验记录···········································5

六.实验总结··········································10

七.思考题或讨论题····································11

附录:

部分代码

 

一.实验目的和要求

1.进一步了解网络编程的过程;

2.掌握Windows环境下基于WinSock的编程方法和通信实现;

3.熟悉客户/服务器模式的网络通信编程实现,编写一个聊天工具,即以客户端和服务器端的模式进行互发消息。

二.实验原理

一个在建立分布式应用时最常用的范例便是客户机/服务器模型。

在这种方案中客户应用程序向服务器程序请求服务。

这种方式隐含了在建立客户机/服务器间通讯时的非对称性。

客户机/服务器模型工作时要求有一套为客户机和服务器所共识的惯例来保证服务能够被提供(或被接受)。

这一套惯例包含了一套协议。

它必须在通讯的两头都被实现。

根据不同的实际情况,协议可能是对称的或是非对称的。

在对称的协议中,每一方都有可能扮演主从角色;在非对称协议中,一方被不可改变地认为是主机,而另一方则是从机。

一个对称协议的例子是Internet中用于终端仿真的TELNET。

而非对称协议的例子是Internet中的FTP。

无论具体的协议是对称的或是非对称的,当服务被提供时必然存在“客户进程”和“服务进程”。

一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一直处于休眠状态,直到一个客户对这个服务的地址提出了连接请求。

在这个时刻,服务程序被“惊醒”并且为客户提供服务-对客户的请求作出适当的反应。

这一请求/相应的过程可以简单的用图2-1表示。

虽然基于连接的服务是设计客户机/服务器应用程序时的标准,但有些服务也是可以通过数据报套接口提供的。

图2-1客户机/服务器模型

三.实验方案与实验步骤

1、客户机/服务器工作流程

图3.1客户机/服务器工作流程

2、聊天室的工作流程

图3.2聊天室工作流程

首先,服务器要创建一个用于侦听的套接字,为该套接字分配地址之后,调用listen()函数使它处于侦听状态;客户机在创建套接字完毕后,为套接字分配地址,然后调用connect()函数,请求与服务器套接字连接;服务器套接字在收到客户机的连接请示后,调用accept()函数,该函数创建一个用于连接的套接字。

应用该套接字和客户机上的连接套接字,用户就可以在服务器和客户机之间进行数据传输了。

在结束传输之后,客户机调用closesocket()函数关闭套接字,服务器也调用该函数关闭用于侦听和连接的套接字。

3、套接字事件处理相关函数

OnAccept():

监听套接字在断口听到连接请求时,应用程序框架调用该函数以告之可以接受或拒绝连接请求,调用Accept来接受请求,建立连接。

OnConnect():

当客户端套接字连接请求完成后,应用程序框架调用该函数,告之是否成功。

OnSend():

框架调用该函数通知该套接字现在可以调用Send函数开始传送数据。

OnReceive():

框架调用该函数通知套接字可以调用Receive函数从数据缓冲区中取数据。

OnClose():

框架调用该函数告之与其相连的对方套接字已被关闭。

4、系统实现

图3.3系统实现过程

四.实验设备与器材配置

电脑、VC6.0

五.实验记录

1、界面

(1)选择:

客户机、服务器;

(2)输入:

服务器名称、服务器端口、发送的消息;

(3)输出显示:

发送的消息、接收的消息、发送和接收消息数目;

(4)按钮:

连接/侦听、断开、发送、清空。

图5.1界面设计

2、功能描述

(1)服务器端

i.建立Socket,绑定端口,并监听;

ii.接受客户端的连接;

iii.与客户端进行通讯;

iv.断开连接。

图5.2服务器端

(2)客户端

i.建立Socket,并申请连接到服务器;

ii.与服务器进行通讯;

iii.断开连接。

图5.3客户机端

3、改进

(1)获取对方主机信息

通过函数gethostname(hostname,sizeof(hostname))得到主机名,客户机获得服务器主机名为2013-20140524WQ,服务器获得客户机主机名为2013-20140524WQ(实验时使用同一台电脑进行调试,所以主机名是一样的),添加到接收信息列表中信息前面。

(2)添加发送接收时间

通过函数time()、localtime()获得当前系统时间,能够显示发送接收时间,格式为年/月/日时/分/秒,添加到接收信息列表中信息首部。

(3)显示发送、接收消息总数

通过m_list.GetCount()函数实现对列表中发送和接收到的信息计数,并显示在界面上,清空列表后,相应的重置为0。

(4)清空列表

通过函数m_list.ResetContent()实现清空列表。

(5)添加背景图片、改变控件背景色、字体等。

上传bmp图片到Bitmap资源文件夹中,在OnPaint()中添加代码,通过不同图片的ID来设置不同的背景图片。

通过加入WM_CTLCOLOR消息,自动生成OnCtlColor()函数,利用SetBkMode()、SetTextColor()、SetBkColor()、CreateSolidBrush()、SetFont()等函数设置背景格式、改变控件背景色和字体大小颜色等。

图5.4改进功能

六.实验总结

在原demo程序的基础上,增加了获取对方主机名、添加发送时间、清空列表等功能,并且尝试添加背景图片,利用WM_CTLCOLOR消息实现对MFC界面的修改。

通过本次实验,我对“点对点”模型有了非常深刻的认识,进一步了解了网络编程的过程,掌握了Windows环境下基于WinSock的编程方法和通讯实现,并且实现了客户端和服务器的连接通信。

对相关套接字事件处理函数OnAccept()、OnConnect()、OnSend()、OnReceive()、OnClose()有了一定了解,熟悉了服务器和客户端不同的工作流程。

七.思考题或讨论题

1、结合所学知识,谈谈自己对TCP三次握手的理解。

1)主机A向主机B发出连接请求数据包:

“我想给你发数据,可以吗?

”,这是第一次对话;

2)主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:

“可以,你什么时候发?

”,这是第二次对话;

3)主机A再发出一个数据包确认主机B的要求同步:

“我现在就发,你接着吧!

”,这是第三次对话。

三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

2、TCP协议有什么优点,根据你的理解说说为什么http要采用TCP作为底层协议?

(1)优点:

面向连接、传输可靠、无拥塞、无乱序、无丢包、完整性检查、可重传;

(2)TCP协议对应于传输层,而HTTP协议对应于应用层,Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。

Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开。

 

附录:

(部分代码)

1、获取对方主机信息添加发送接收时间

voidCTalkDlg:

:

OnReceive()

{

CStringmDay;

CStringmTime;

CStringttime;

time_tt1;

t1=time(NULL);//机器时间

structtm*p;

p=localtime(&t1);//转换为本地时间

mDay.Format("%4d/%2d/%2d",1900+p->tm_year,1+p->tm_mon,p->tm_mday);

mTime.Format("%3d:

%2d:

%2d",p->tm_hour,p->tm_min,p->tm_sec);

char*pBuf=newchar[1025];//charpBuf[1025];

intnBufSize=1024;

intnReceived;

charhostname[100];

CStringstrReceived;

nReceived=m_sConnectSocket.Receive(pBuf,nBufSize);//接收消息

//判断消息接收是否成功?

if(nReceived!

=SOCKET_ERROR)

{

gethostname(hostname,sizeof(hostname));//获取对方主机信息

pBuf[nReceived]=NULL;//保留接收消息的有效部分

strReceived=pBuf;//将消息转化为CString对象

//添加主机信息和发送时间

strReceived=mDay+mTime+""+hostname+":

"+strReceived;

//将消息添加到“已接收的消息”列表框

m_listReceived.AddString(strReceived);

m_Countb=m_listReceived.GetCount();//显示接收信息数

UpdateData(FALSE);//更新对话框

}

else

{

AfxMessageBox("信息接收错误!

",MB_OK|MB_ICONSTOP);

}

deletepBuf;

}

2、显示发送、接收消息总数

voidCTalkDlg:

:

OnSendMsg()

{

CStringmDay;

CStringmTime;

CStringttime;

time_tt1;

t1=time(NULL);//机器时间

structtm*p;

p=localtime(&t1);//转换为字符串时间

mDay.Format("%4d/%2d/%2d",1900+p->tm_year,1+p->tm_mon,p->tm_mday);

mTime.Format("%3d:

%2d:

%2d",p->tm_hour,p->tm_min,p->tm_sec);

intnLen;//消息长度

intnSent;//已发送消息的长度

//从对话框取回数据

UpdateData(TRUE);

//判断要发送的消息是否为空

if(!

m_strMsg.IsEmpty())

{

nLen=m_strMsg.GetLength();//获取消息的长度

nSent=m_sConnectSocket.Send(LPCTSTR(m_strMsg),nLen);//发送消息

if(nSent!

=SOCKET_ERROR)//发送是否成功

{

//添加主机信息和发送时间

m_strMsg=mDay+mTime+"send:

"+m_strMsg;

//将消息添加到“已发送列表框”

m_listSent.AddString(m_strMsg);

m_Counta=m_listSent.GetCount();//显示发送信息数

UpdateData(FALSE);//更新对话框

}

else

{

AfxMessageBox("信息发送错误",MB_OK|MB_ICONSTOP);

}

m_strMsg.Empty();//清除当前信息

UpdateData(FALSE);

}

}

3、清空列表

voidCTalkDlg:

:

OnButton1()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

m_listSent.ResetContent();//清空发送列表

m_Counta=m_listSent.GetCount();//重置发送消息数

UpdateData(FALSE);

}

voidCTalkDlg:

:

OnButton2()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

m_listReceived.ResetContent();//清空接受列表

m_Countb=m_listReceived.GetCount();//重置接收消息数

UpdateData(FALSE);

}

4、添加背景图片

voidCTalkDlg:

:

OnPaint()

{

if(IsIconic())

{

CPaintDCdc(this);//devicecontextforpainting

SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);

//Centericoninclientrectangle

intcxIcon=GetSystemMetrics(SM_CXICON);

intcyIcon=GetSystemMetrics(SM_CYICON);

CRectrect;

GetClientRect(&rect);

intx=(rect.Width()-cxIcon+1)/2;

inty=(rect.Height()-cyIcon+1)/2;

//Drawtheicon

dc.DrawIcon(x,y,m_hIcon);

}

else

{

//CDialog:

:

OnPaint();

CPaintDCdc(this);

CRectrect;

GetClientRect(&rect);

CDCdcMem;

dcMem.CreateCompatibleDC(&dc);

CBitmapbmpBackground;

bmpBackground.LoadBitmap(IDB_BITMAP3);//IDB_BITMAP3是对应的ID

BITMAPbitmap;

bmpBackground.GetBitmap(&bitmap);

Cbitmap*pbmpOld=dcMem.SelectObject(&bmpBackground);dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,

bitmap.bmWidth,bitmap.bmHeight,SRCCOPY);

}

}

5、改变背景色、字体大小颜色

HBRUSHCProject2Dlg:

:

OnCtlColor(CDC*pDC,CWnd*pWnd,UINTnCtlColor)

{

HBRUSHhbr=CDialog:

:

OnCtlColor(pDC,pWnd,nCtlColor);

//TODO:

ChangeanyattributesoftheDChere

//设置显示字体

CFont*cFont=newCFont;

cFont->CreateFont(16,0,0,0,FW_SEMIBOLD,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,"Arial");

if(pWnd==this)//改变整个界面背景色

{

HBRUSHbrush=CreateSolidBrush(RGB(199,237,204));

return(HBRUSH)brush;

}

switch(nCtlColor)

{

caseCTLCOLOR_STATIC:

//对所有静态文本控件的设置

{

pDC->SetBkMode(TRANSPARENT);//设置背景为透明

pDC->SetTextColor(RGB(255,255,0));//设置字体颜色

pWnd->SetFont(cFont);//设置字体

HBRUSHB=CreateSolidBrush(RGB(199,237,204));//创建画刷

return(HBRUSH)B;//返回画刷句柄

}

break;

default:

returnCDialog:

:

OnCtlColor(pDC,pWnd,nCtlColor);

}

//TODO:

Returnadifferentbrushifthedefaultisnotdesired

returnhbr;

}

 

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

当前位置:首页 > 工程科技 > 电子电路

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

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