mfc三视图和斜等测图实现_编程实现TCP协议数据传输

1.实验目的

① 通过本实验加深对TCP协议传输数据过程的理解。

② 学习套接字的使用。

2.实验内容

以使用Visual C++程序设计语言,编写TCP传输数据的程序,在两台计算机上实现TCP数据传输为例,要求实现以下功能:

① 在一个工程中,创建一个对话框,包括“发送数据”和“接收数据”窗口。

② 一台计算机在发送数据窗口,输入目标计算机的IP地址和发送的对话内容,目标计算机在接收数据窗口能够显示对方发送的数据信息。

③ 编程实现两台计算机相互发送和接收数据信息。

3.实验步骤

① 启动Visual C++ 6.0,用MFC创建对话框。

② 选择“文件”→“新建”命令,在弹出的对话框中选择“MFC Appwizard[exe]”选项,工程名为“Chat”。

③ 在“您要创建的应用程序类型”对话框中,选择“基本对话框”单选按钮,完成默认窗口的建立,删除默认窗口中的“按钮”和“编辑框”。

④ 建立数据传输对话框。

l 选择控件中的“编辑框”控件,在对话框的上方和右下方分别建立“发送”和“接收”数据内容窗口。

l 选择“IP地址”控件,在对话框的下方左侧建立所要输入的目标地址窗口。

l

84c32e705b54cfc2d4f86da2f46a6199.png

选择“按钮”控件,实现发送数据操作。

l 创建两个“组框”分别起名为“接收数据”和“发送数据”,以实现程序的可视效果。完成后的对话框如图6-9所示。

⑤ 为了编程方便,将接收“编辑框”和发送“编辑框”的ID改为IDC_EDIT_RECV和IDC_EDIT_SEND,按钮的属性改为IDC_BTN_SEND。

⑥ 参考程序

//调用套接字初始化函数

BOOL CChatDlg::OnInitDialog()

{

CDialog::OnInitDialog();

......

// TODO: Add extra initialization here在该句下添加以下内容

InitSocket();

RECVPARAM *pRecvParam=new RECVPARAM;

pRecvParam->sock=m_socket;

pRecvParam->hwnd=m_hWnd;

HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);

CloseHandle(hThread);

}

在接收数据时,如果没有数据到来,则recvfrom函数则会阻塞,从而导致程序暂停运行,所以将接收数据的工作放到单独的线程来完成。给线程传递两个参数,一个是创建的套接字,一个是对话框的句柄,即接收编辑框的句柄,当线程接收到数据之后,可以将数据传回给对话框中的编辑框,经过处理后显示。

//对套接字进行初始化 自定义函数

BOOL CChatDlg::InitSocket()

{

m_socket=socket(AF_INET,SOCK_DGRAM,0); //创建用于监听的套接字

if(INVALID_SOCKET==m_socket)

{

MessageBox("套接字创建失败");

return FALSE;

}

//绑定套接字

SOCKADDR_IN addrSock;

addrSock.sin_family=AF_INET; //地址族 AF_INET

addrSock.sin_port=htons(6000); //分配给套接字的端口

addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
// IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据

int retval;

retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
//将该套接字绑定到本地的某个地址和端口上

if(SOCKET_ERROR==retval)

{

closesocket(m_socket);

MessageBox("绑定失败");

return FALSE;

}

return TRUE;

}

//在CChatDlg头文件里增加以下内容

#define WM_RECVDATA WM_USER+1 //增加自定义WM_RECVDATA消息的定义

struct RECVPARAM //增加RECVPARAM结构体的定义

{

SOCKET sock;

HWND hwnd;

};

afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);
// 增加消息响应函数原型的声明

//接收数据,自定义线程函数,该函数一直在执行

DWORD WINAPI RecvProc(LPVOID lpParameter)

{

SOCKET sock=((RECVPARAM*)lpParameter)->sock;

HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;

SOCKADDR_IN addrFrom; //接收客户端的地址信息

int len=sizeof(SOCKADDR);

char recvBuf[200];

char tempBuf[300];

int retval;

while(TRUE)

{

retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);

if(SOCKET_ERROR==retval)

{

break;

}

printf(tempBuf,"%s 说:%s",inet_ntoa(addrFrom.sin_addr),recvBuf);

//将数据传给对话框

::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
//发送消息,只要一有消息,就发送RECVDATA消息,也就是调用函数OnRecvData()

}

return 0;

}

//把接收到的数据在编辑框IDC_EDIT_RECV里进行显示

void CChatDlg::OnRecvData(WPARAM wParam, LPARAM lParam)

{

CString str=(char *)lParam;

CString strTemp;

GetDlgItemText(IDC_EDIT_RECV,strTemp);
//在网络中接收到的内容存储到strTemp变量中,然后显示到接收窗口中

str+="rn";

str+=strTemp;

SetDlgItemText(IDC_EDIT_RECV,str);

}

// 发送数据,单击“发送”按钮的消息响应函数

void CChatDlg::OnBtnSend()

{

DWORD dwIP;

//首先得到控件指针

((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
//地址变量窗口

SOCKADDR_IN addrTo;

addrTo.sin_family=AF_INET;

addrTo.sin_port=htons(6000);

addrTo.sin_addr.S_un.S_addr=htonl(dwIP);

CString strSend;

GetDlgItemText(IDC_EDIT_SEND,strSend);//发送窗口的内容存储在变量strSend中

sendto(m_socket,strSend,strSend.GetLength()+1,0, (SOCKADDR*)&addrTo,sizeof(SOCKADDR));

SetDlgItemText(IDC_EDIT_SEND,"");

}

⑦ 以下为两台计算机的程序运行结果,设计算机1的IP地址为192.168.32.110,计算机2的IP地址为192.168.32.117。图6-10所示为计算机1给计算机2发送的消息,图6-11所示为计算机2给计算机1回应的消息,图6-12为计算机1收到的计算机2回应信息。

f0003341fc5e95e5057becf343ce8664.png

ac8e81284636c3a4081b1c9d3017b767.png


图6-10 计算机1发送消息窗口 图6-11 计算机2发送消息窗口

52e376947ceb2aad3821fd9dfd6f961b.png


图6-12 计算机1收到的回应消息窗口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值