东南大学计算机与网络第四次实验.docx
- 文档编号:10782236
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:25
- 大小:205.04KB
东南大学计算机与网络第四次实验.docx
《东南大学计算机与网络第四次实验.docx》由会员分享,可在线阅读,更多相关《东南大学计算机与网络第四次实验.docx(25页珍藏版)》请在冰点文库上搜索。
东南大学计算机与网络第四次实验
东南大学自动化学院
实验报告
课程名称:
信息通信网络概论
第4次实验
实验名称:
设计协议
院(系):
自动化专业:
自动化
姓名:
学号:
实验室:
金智楼实验组别:
同组人员:
实验时间:
2013年12月23日
评定成绩:
审阅教师:
目录
一.实验目的和要求………………………………………………3
二.实验原理………………………………………………………3
三.实验方案与实验步骤…………………………………………4
四.实验设备与器材配置…………………………………………5
五.实验记录………………………………………………………5
六.实验总结………………………………………………………9
七.思考题或讨论题………………………………………………9
一.实验目的和要求
目的:
1.设计简单的应用层协议,
2.开发基于TCP/IP或UDP/IP的网络通信程序,实现数据传送和文件传输。
要求:
1.正确理解应用层协议的概念;
2.更深入了解客户/服务器模式的网络程序设计。
二.实验原理
1.应用层协议
应用层协议的定义包括如下内容:
(1)交换的报文类型,如请求报文和响应报文;
(2)各种报文类型的语法,如报文中的各个字段公共详细描述;
(3)字段的语义,即包含在字段中信息的含义;
(4)进程何时、如何发送报文及对报文进行响应。
有些应用层协议是由RFC文档定义的,因此它们位于公共领域。
例如,web的应用层的协议HTTP(超文本传输协议,RFC2616)就作为一个RFC供大家使用。
如果浏览器开发者遵从HTTPRFC规则,所开发出的浏览器就能访问任何遵从该文档标准的web,服务器并获取相应的web页面。
还有很多别的应用层协议是专用的.不能随意应用于公共领域。
例如,很多现有的P2P文件共享系统使用的是专用应用层协议。
目的,应用层协议主要有以下几种。
2)SOCKET编程
服务器要创建一个用于侦听的套接字,为该套接字分配地址之后,调用listen()函数使它处于侦听状态;客户机在创建套接字完毕后,为套接字分配地址,然后调用connect()函数,请求与服务器套接字连接;服务器套接字在收到客户机的连接请示后,调用accept()函数,该函数创建一个用于连接的套接字。
应用该套接字和客户机上的连接套接字,用户就可以在服务器和客户机之间进行数据传输了。
在结束传输之后,客户机调用closesocket()函数关闭套接字,服务器也调用该函数关闭用于侦听和连接的套接字。
三.实验方案与实验步骤
1.基于TCP的socket编程
1)服务端
1)建立Socket初始化WinSock的动态连接库后,需要在服务器端建立一个监听的Socket,为此可以调用Socket()函数用来建立这个监听的Socket,并定义此Socket所使用的通信协议。
此函数调用成功返回Socket对象,失败则返回INVALID_SOCKET(调用WSAGetLastError()可得知原因,所有WinSocket的函数都可以使用这个函数来获取失败的原因)。
2)绑定端口接下来要为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。
3)监听当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。
listen()函数使服务器端的Socket进入监听状态,并设定可以建立的最大连接数(目前最大值限制为5,最小值为1)。
该函数调用成功返回0,否则返回SOCKET_ERROR。
服务器端的Socket调用完listen()后,如果此时客户端调用connect()函数提出连接申请的话,Server端必须再调用accept()函数,这样服务器端和客户端才算正式完成通信程序的连接动作。
为了知道什么时候客户端提出连接要求,从而服务器端的Socket在恰当的时候调用accept()函数完成连接的建立,我们就要使用WSAAsyncSelect()函数,让系统主动来通知我们有客户端提出连接请求了。
该函数调用成功返回0,否则返回SOCKET_ERROR。
4)服务器端接受客户端的连接请求当Client提出连接请求时,Server端hwnd视窗会收到WinsockStack送来我们自定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。
为了使服务器端接受客户端的连接请求,就要使用accept()函数,该函数新建一Socket与客户端的Socket相通,原先监听之Socket继续进入监听状态,等待他人的连接要求。
该函数调用成功返回一个新产生的Socket对象,否则返回INVALID_SOCKET。
5)结束socket连接结束服务器和客户端的通信连接是很简单的,这一过程可以由服务器或客户机的任一端启动,只要调用closesocket()就可以了,而要关闭Server端监听状态的socket,同样也是利用此函数。
2)客户端
1)建立客户端的Socket客户端应用程序首先也是调用WSAStartup()函数来与Winsock的动态连接库建立关系,然后同样调用socket()来建立一个TCP或UDPsocket(相同协定的sockets才能相通,TCP对TCP,UDP对UDP)。
与服务器端的socket不同的是,客户端的socket可以调用bind()函数,由自己来指定IP地址及port号码;但是也可以不调用bind(),而由Winsock来自动设定IP地址及port号码。
2)提出连接申请客户端的Socket使用connect()函数来提出与服务器端的Socket建立连接的申请,函数调用成功返回0,否则返回SOCKET_ERROR。
3)数据的传送虽然基于TCP/IP连接协议(流套接字)的服务是设计客户机/服务器应用程序时的主流标准,但有些服务也是可以通过无连接协议(数据报套接字)提供的。
2.基于UDP的socket编程
服务器端
1:
创建套接字(create)
2:
将套接字绑定到一个本地地址和端口上(bind)
3:
等待接收数据(recvfrom)
4:
关闭套接字
客户端
1:
创建套接字(create)
2:
向服务器发送数据(sendto)
3:
关闭套接字
四.实验设备与器材配置
计算机一台、软件MicrosoftVisualStudio6.0
五.实验记录
打开两个应用程序,一个选择“服务器”,并且点击“侦听”;另外一个选择“客户端”,并且点击“连接”,此时两个程序的消息发送窗口的信息框变为可写,输入消息可以进行客户端-服务器之间的发送和接收,发送和接收的消息可以存储在信息框内。
客户端和服务器端可以互发信息:
输入框输入/n和/p,接收到的为指定的图像:
主要代码如下:
voidCProject2Dlg:
:
OnSelchangeComboCs()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
intset=m_cs_set.GetCurSel();
if(set==1)
{
m_server=FALSE;
this->GetDlgItem(IDC_SET_IPADDR)->EnableWindow(TRUE);
m_set_ip="127.0.0.1";
UpdateData(false);
this->SetDlgItemText(IDC_CONNECT,"连接");
this->SetWindowText("TCP/IP通信-客户端");
}
elseif(set==0)
{
m_server=TRUE;
m_set_ip="";
this->GetDlgItem(IDC_SET_IPADDR)->EnableWindow(FALSE);
UpdateData(FALSE);
this->SetDlgItemText(IDC_CONNECT,"侦听");
this->SetWindowText("TCP/IP通信-服务器端");
}
}
voidCProject2Dlg:
:
OnConnect()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData(TRUE);
intretb,ret,retc;
SOCKADDR_INaddr;
BOOLnret;
CStringServerIP;
ServerIP=m_set_ip;
if(m_active==TRUE)
return;
if(m_server==TRUE)
{
if(((m_set_port)<=1024)||((m_set_port)>4096))
{
AfxMessageBox("请输入合理的端口号!
");
}
ret=m_listensocket.Create(m_set_port,SOCK_STREAM);
if(ret==false)
{
m_static_state="无法建立服务器!
";
UpdateData(FALSE);
m_listensocket.Close();
}
retb=m_listensocket.Listen(5);
if(retb==false)
{
m_static_state="无法侦听!
!
!
";
UpdateData(FALSE);
}
m_static_state="服务器建立成功!
正在侦听……";
m_list_msg.ResetContent();
m_list_msg.AddString("====>服务器正在侦听……");
this->GetDlgItem(IDC_CONNECT)->EnableWindow(FALSE);
this->GetDlgItem(IDC_COMBO_CS)->EnableWindow(FALSE);
UpdateData(FALSE);
m_active=TRUE;
}
else
{
ServerIP.TrimLeft();
ServerIP.TrimRight();
if(inet_addr(ServerIP)==INADDR_NONE)
{
AfxMessageBox("请输入正确的服务器IP地址!
");
}
if(((m_set_port)<=1024)||((m_set_port)>4096))
{
AfxMessageBox("请输入合理的端口号!
");
}
retc=m_connectsocket.Create(0,SOCK_STREAM);
if(retc==false)
{
m_static_state="无法建立客户端!
";
UpdateData(FALSE);
m_connectsocket.Close();
}
addr.sin_family=AF_INET;
addr.sin_port=htons(m_set_port);
addr.sin_addr.S_un.S_addr=inet_addr(m_set_ip);
nret=m_connectsocket.Connect((SOCKADDR*)&addr,sizeof(SOCKADDR));
if(nret==TRUE)
{
AfxMessageBox("连接服务器失败!
!
");
m_connectsocket.Close();
}
else
{
m_static_state="正在连接服务器……";
this->GetDlgItem(IDC_CONNECT)->EnableWindow(FALSE);
this->GetDlgItem(IDC_COMBO_CS)->EnableWindow(FALSE);
UpdateData(FALSE);
m_active=TRUE;
}
}
}
voidCProject2Dlg:
:
OnServerAccept()
{
if(m_active==TRUE)
{
m_listensocket.Accept(m_connectsocket,NULL,NULL);
m_static_state="客户端已连接上——";
m_list_msg.AddString("====>客户端连接成功!
");
UpdateData(FALSE);
CStringwelcome("Welcomemyfriend!
");
m_connectsocket.Send(welcome,welcome.GetLength());
}
}
voidCProject2Dlg:
:
OnClientConnect(intnErrorCode)
{
sockaddr_inname;
intlen;
CStringbuf;
if(m_active==TRUE)
{
if(nErrorCode!
=0)
{
m_list_msg.AddString("连接服务器错误!
");
m_static_state="服务器连接错误……";
this->GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
this->GetDlgItem(IDC_COMBO_CS)->EnableWindow(TRUE);
UpdateData(FALSE);
m_active=FALSE;
m_connectsocket.Close();
}
else
{
len=sizeof(sockaddr_in);
m_connectsocket.GetPeerName((SOCKADDR*)&name,&len);
m_list_msg.ResetContent();
buf="成功连接上服务器";
buf+=inet_ntoa(name.sin_addr);
m_list_msg.AddString(buf);
m_static_state="服务器连接成功!
";
UpdateData(FALSE);
CStringwelcome("Iam");
welcome+=CLIENT;
m_connectsocket.Send(welcome,welcome.GetLength());
}
}
}
voidCProject2Dlg:
:
OnServerClose()
{
m_connectsocket.Close();
m_static_state="正在侦听……";
m_list_msg.ResetContent();
m_list_msg.AddString("====>客户端已退出……");
m_list_msg.AddString("====>服务器正在侦听……");
UpdateData(FALSE);
}
voidCProject2Dlg:
:
OnSocketClose()
{
if(m_active==FALSE)
return;
if(m_server==TRUE)
{
OnServerClose();
}
else
{
OnClientClose();
}
}
voidCProject2Dlg:
:
OnClientClose()
{
m_connectsocket.Close();
m_list_msg.ResetContent();
m_list_msg.AddString("服务器已断开。
成功退出……");
m_static_state="已断开连接……";
this->GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
this->GetDlgItem(IDC_COMBO_CS)->EnableWindow(TRUE);
UpdateData(FALSE);
m_active=FALSE;
}
voidCProject2Dlg:
:
OnSocketReceive()
{
if(m_server==TRUE)
{
OnServerReceive();
}
else
{
OnClientReceive();
}
}
voidCProject2Dlg:
:
OnServerReceive()
{
BOOLAct=FALSE;
CStringnRev,nret;
charbuf[MAX_BUFFER+1];
intret,i,len;
ret=m_connectsocket.Receive(buf,MAX_BUFFER,0);
if(ret!
=SOCKET_ERROR)
{
buf[ret]=NULL;
nRev=buf;
nret+=CLIENT;
nret+=":
";
len=nret.GetLength();
nret=nRev.Right(((nRev.GetLength())-len));
if(nret.GetAt(0)=='/')
{
Act=DoAction(nret);
}
if(Act==FALSE)
{
m_list_msg.AddString((LPCTSTR)nRev);
}
i=m_list_msg.GetCount();
m_list_msg.SetCurSel(i-1);
m_list_msg.SetCurSel(-1);
UpdateData(FALSE);
}
else
AfxMessageBox("消息接收错误!
");
}
voidCProject2Dlg:
:
OnClientReceive()
{
charbuf[MAX_BUFFER+1];
BOOLAct=FALSE;
intret,i,len;
CStringnRev,nret;
ret=m_connectsocket.Receive(buf,MAX_BUFFER,0);
if(ret!
=SOCKET_ERROR)
{
buf[ret]=NULL;
nRev=buf;
nret+=SERVER;
nret+=":
";
len=nret.GetLength();
nret=nRev.Right(((nRev.GetLength())-len));
if(nret.GetAt(0)=='/')
{
Act=DoAction(nret);
}
if(Act==FALSE)
{
m_list_msg.AddString((LPCTSTR)nRev);
}
i=m_list_msg.GetCount();
m_list_msg.SetCurSel(i-1);
m_list_msg.SetCurSel(-1);
UpdateData(FALSE);
}
else
AfxMessageBox("消息接收错误!
");
}
voidCProject2Dlg:
:
OnSendMsg()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringbuf;
intnret;
BOOLAct=FALSE;
intnLen,i;
UpdateData(TRUE);
m_outmsg.TrimLeft();
if(m_outmsg.IsEmpty())
{
AfxMessageBox("对不起,不能发送空消息!
");
return;
}
if(m_server==TRUE)
{
buf+=SERVER;
buf+=":
";
}
else
{
buf+=CLIENT;
buf+=":
";
}
buf+=m_outmsg;
nLen=buf.GetLength();
nret=m_connectsocket.Send((LPCTSTR)buf,nLen);
if(nret!
=SOCKET_ERROR)
{
if(m_outmsg.GetAt(0)=='/')
{
Act=DoAction(m_outmsg);
}
if(Act==FALSE)
{
m_list_msg.AddString((LPCTSTR)buf);
}
m_outmsg.Empty();
i=m_list_msg.GetCount();
m_list_msg.SetCurSel(i-1);
m_list_msg.SetCurSel(-1);
UpdateData(FALSE);
}
else
AfxMessageBox("消息发送失败!
:
(");
}
m_sListenSocket.Accept(m_sConnectSocket);
//激活消息输入和相关控件
GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE);
GetDlgItem(IDOK)->EnableWindow(TRUE);
GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE);
}
voidCTalkDlg:
:
OnConnect()
{
//对于客户机
GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE);
GetDlgItem(IDOK)->EnableWindow(TRUE);
GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE);
GetDlgItem(IDC_BTN_CLOSE)->EnableWindow(TRUE);
}
voidCTalkDlg:
:
OnReceive()
{
char*pBuf=newchar[1025];
//charpBuf[1025];
intnBufSize=1024;
intnRec
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 东南大学 计算机 网络 第四 实验