中国石油大学(华东)VC实验报告实验八

  • 格式:docx
  • 大小:199.29 KB
  • 文档页数:9

下载文档原格式

  / 9
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中国石油大学(华东)自动化专业VC 实验报告

班级: 自动化1602 姓名: 谢清涛 学号: 1605010224

实验八 Windows 网络通信应用编程

一、实验目的

1、熟悉 Visual Studio 开发环境;

2、掌握 MFC 程序中菜单资源的设计方法;

3、掌握 socket 通信的基本概念和 socket 通信

MFC 类的编程方法;

二、实验内容

如图所示,创建单文档应用程序,实现 TCP 通信服务器和客户端功能。 设计要求:

(1) TCP 服务器方面,创建启动监听、停止监听和发送数据三个按钮,实现 TCP 服务器的监听

功能和通信功能;

(2) TCP 客户端方面,创建建立连接、断开连接和发送数据三个按钮,实现 TCP 客户端的连接

功能和通信功能;

实验日期: 成 绩:

三、实验报告

(1) 总结TCP 通信的基本流程;

A、服务器初始化——LISTEN

(1)调用socket函数创建文件描述符。

(2)调用bind函数将当前的文件描述符和ip/port绑定在一起。如果这个端口已经被其他进程占用了,就会bind失败。

(3)调用listen函数声明当前这个文件描述符作为一个服务器的文件描述符,为accept做好准备。(4)调用accept函数阻塞等待客户端连接起来。

B、建立连接的过程——三次握手

第一次:调用connect函数发出SYN段向服务器发起连接请求,并阻塞等待服务器应答。

第二次:服务器收到客户端的SYN段后,会应答一个SYN-ACK段表示“同一建立连接”。

第三次:服务器端收到SYN-ACK后会从connect函数中返回,同时应答一个ACK段。

C、数据传输的过程

建立连接后,TCP协议提供全双工的通信服务。所谓全双工,意思是:在同一条链路中的同一时刻,通信双方可以同时写数据。相对的概念叫做半双工,即:在同一条链路中的同一时刻,只能由一方来写数据。

(1)服务器从accept函数返回后立刻调用read函数读socket里的数据。读socket就像读管道一样,如果没有数据到达就阻塞等待。

(2)客户端调用write函数发送请求给服务器,服务器收到后就向客户端回复ACK,并从read函数中返回,对客户端的请求进行处理。在此期间客户端调用read函数阻塞等待服务器的应答。(3)服务器调用write函数将处理结果发回客户端,客户端收到后就回复ACK。服务器再次调用read函数阻塞等待下一条请求,。

(4)客户端从read函数中返回,并发送下一条请求,如此循环下去。

D、断开连接的过程——四次挥手

第一次:如果客户端没有更多的请求就调用close函数关闭连接,客户端会向服务器端发送FIN端。第二次:服务器收到FIN后会回应一个ACK,同时read返回0。

第三次:客户端收到FIN后,再返回一个ACK给服务器。

(2) 列出实现TCP 服务器端功能的代码清单;

CMyServer::CMyServer()

{

}

CMyServer::~CMyServer()

{

CMySocket *pSocket;

POSITION pos = m_ClientList.GetHeadPosition();

while(pos)

{

pSocket = (CMySocket*)m_ClientList.GetNext(pos);

pSocket->Close();

delete pSocket;

pSocket = NULL;

}

m_ClientList.RemoveAll();

}

void CMyServer::OnAccept(int nErrorCode)

{

CMySocket *pSocket = new CMySocket();

if(Accept(*pSocket))

{

m_ClientList.AddTail(pSocket);

pSocket->AsyncSelect(FD_READ|FD_CLOSE);

pSocket->SetMsgPara(m_pWnd,m_nMsgID);

pSocket->m_bAccept = TRUE;

m_pWnd->SendMessage(m_nMsgID, DAQ_LINK_ACCEPT,(LPARAM)pSocket);

}

else

{

delete pSocket;

pSocket = NULL;

}

}

void CMyServer::BroadcastData(BYTE TxData[], int len)

{

CMySocket *pSocket;

POSITION pos = m_ClientList.GetHeadPosition();

while(pos)

{

pSocket = (CMySocket*)m_ClientList.GetNext(pos);

pSocket->SendData(TxData,len);

}

}

BOOL CMyServer::SendData(BYTE TxData[], int len, CMySocket *pSocket)

{

CMySocket *m_pSocket;

POSITION pos = m_ClientList.GetHeadPosition();

while(pos)

{

m_pSocket = (CMySocket*)m_ClientList.GetNext(pos);

if(m_pSocket == pSocket)

{

m_pSocket->SendData(TxData,len);

}

}

return TRUE;

}

void CMyServer::ReadData(BYTE RxData[], int &len, CMySocket *pSocket)

{

if(pSocket != NULL)

{

len = pSocket->ReadData(RxData);