计算机网络大作业

更新时间:2024-04-04 04:17:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

计算机网络大作业

专业: 班级: 姓名: 学号:

一、介绍

该通信软件是基于C/S模式开发,是用MFC的WinSock编程原理。该应用程序的技术主要有一下几点:

1、从CAsyncSocket类派生出自己所需要的WinSock类 2、WinSock类与应用程序框架之间的关系 3、流式套接字的使用 4、网络事件

CAsyncSocket类是在很底程度上对Winsock API的封装,他提供的低级接口几乎与WinSock API的函数调用直接对应,CAsyncSocket类是从CObject类派生而来。

所谓套接字(socket)是一种网络变成接口,它是对通信短点的一种抽象,提供了一种发送和接收数据的机制。套接字是通信的基石,一个套接字是通信的一端。在通信的任何一端上,用户可以找到与套接字对应的一个套接字名字,每一个正在被使用的套接字都有它的类型和与其相关的进程。套接字存在于通信域中,通信域是为了处理一般的通过套接字通信的线程而引进的一种抽象概念。

二、整体流程图

1、启动与发送 开始启动服务器,使其处于侦听状态启动客户机,与服务器进行连接发送数据是否发送成功否提示:发送失败!是将数据显示在 发送的数据列表框中 2、接收 开始接收数据的事件被触发显示受到的数据到 接收的数据 列表框中 二、主要代码

1、创建派生的套接字类之后,向该套接字中添加一个成员变量,用作指向父对话框口德指针。

//设置CTalkDlg类的指针

void CMySocket::SetParent(CTalkDlg *pDlg) { //设置成员变量 m_pDlg=pDlg; }

2、接收、连接、关闭是近啊处理函数

//事件处理函数

void CMySocket::OnAccept(int nErrorCode) { if(nErrorCode==0) //call the dialog's OnAccept function m_pDlg->OnAccept(); }

//事件处理函数

void CMySocket::OnConnect(int nErrorCode) { if (nErrorCode==0) m_pDlg->OnConnect(); }

void CMySocket::OnRecive(int nErrorCode) { if(nErrorCode==0)

m_pDlg->OnReceive(); }

void CMySocket::OnClose(int nErrorCode) { if(nErrorCode==0) m_pDlg->OnClose(); }

3、因为对话框需要两个套接字,所以要向对话框类(CTalkDlg)中添加两个成员变量。

public:

CMySocket m_sConnectSocket; CMySocket m_sListenSocket;

4、为对话框中所有的变量添加初始化代码。

BOOL CTalkDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add \ // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

} } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //初始化控制变量

m_cmbType.SetCurSel(1); m_strServName=\ m_nServPort=1000; //更新控制变量 UpdateData(FALSE); //设置套接字成员的CTalkDlg类指针 m_sListenSocket.SetParent(this); m_sConnectSocket.SetParent(this); return TRUE; // return TRUE unless you set the focus to a control }

5、建立客户机与服务器之间的连接

void CTalkDlg::OnBinConnect() { // TODO: Add your control notification handler code here //从对话框中取出数据 UpdateData(TRUE); //禁用链接和类型相关控件 GetDlgItem(IDC_BIN_CONNECT)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(FALSE); GetDlgItem(IDC_STATIC_SERVNAME)->EnableWindow(FALSE); GetDlgItem(IDC_STATIC_SERVPORT)->EnableWindow(FALSE); GetDlgItem(IDC_COMBO_TYPE)->EnableWindow(FALSE); //判断当前是客户端还是服务器 if(m_cmbType.GetCurSel()==0) { //服务器 //创建用于设置端口绑定的套接字 m_sListenSocket.Create(m_nServPort); //开始侦听请求链接 m_sListenSocket.Listen(); } else { //客户机 //创建一个默认的套接字 m_sConnectSocket.Create(); //发出链接请求 m_sConnectSocket.Connect(m_strServName,m_nServPort); }

}

void CTalkDlg::OnAccept() { //此函数用于服务器 //接受链接请求 m_sListenSocket.Accept(m_sConnectSocket); //激活消息输入和发送的相关控件 GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE); GetDlgItem(IDOK)->EnableWindow(TRUE); GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE); }

void CTalkDlg::OnConnect() { //此处用于\客户机\ //激活消息输入和发送的相关控件 GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE); GetDlgItem(IDOK)->EnableWindow(TRUE); //botton send GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE); //激活\关闭\按钮,这仅对\客户机\有效 GetDlgItem(IDC_BIN_CLOSE)->EnableWindow(TRUE); }

6、发送和接收数据

void CTalkDlg::OnSendMsg() { // TODO: Add your control notification handler code here int nLen;//消息长度 int nSent;//已发送消息的长度 //从对话筐中取出数据 UpdateData(TRUE); //判断要发送的消息是否为空 if(!m_strMsg.IsEmpty()) { //获取消息的长度 nLen=m_strMsg.GetLength(); //发送消息 nSent=m_sConnectSocket.Send(LPCTSTR(m_strMsg),nLen); //判断发送是否成功 if(nSent!=SOCKET_ERROR) {

//发送成功,将消息添加到“发送的消息“列表框 m_listSent.AddString(m_strMsg); UpdateData(FALSE); } else { AfxMessageBox(\信息发送错误!\ } //清除当前消息 m_strMsg.Empty(); //更新对话框数据 UpdateData(FALSE); } }

void CTalkDlg::OnReceive() { char *pBuf=new char[1025]; int nBufSize=1024; int nReceived; CString strReceived; //接收消息 nReceived=m_sConnectSocket.Receive(pBuf,nBufSize); //判断接收是否成功 if(nReceived!=SOCKET_ERROR) { //保留接收消息的有效部分 pBuf[nReceived]=NULL; //将消息转化为CString对象 strReceived=pBuf; //将消息添加到“接收的消息”列表中 m_listReceived.AddString(strReceived); //更新对话筐数据 UpdateData(FALSE); } else { //发送消息失败,给出错误提示 AfxMessageBox(\信息接收错误!\ } }

7、终止连接

void CTalkDlg::OnClose() { //关闭连接的套接字 m_sConnectSocket.Close(); //禁用消息输入和发送的相关控件 GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE); GetDlgItem(IDOK)->EnableWindow(FALSE);//botton send GetDlgItem(IDC_STATIC_MSG)->EnableWindow(FALSE); GetDlgItem(IDC_BIN_CLOSE)->EnableWindow(FALSE); //清除列表框中的内容 while(m_listSent.GetCount()!=0) m_listSent.DeleteString(0); while(m_listReceived.GetCount()!=0) m_listReceived.DeleteString(0); //如果是“客户机” if(m_cmbType.GetCurSel()==1) { //对于客户机 //激活与连接相关的控件 GetDlgItem(IDC_BIN_CONNECT)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT_SERVNAME)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT_SERVPORT)->EnableWindow(TRUE); GetDlgItem(IDC_STATIC_SERVNAME)->EnableWindow(TRUE); GetDlgItem(IDC_STATIC_SERVPORT)->EnableWindow(TRUE); GetDlgItem(IDC_COMBO_BOX)->EnableWindow(TRUE); } }

void CTalkDlg::OnBinClose() { // TODO: Add your control notification handler code here //调用OnClose()成员函数 OnClose(); }

四、运行截图

1、启动服务器,使服务器处于侦听状态

2、启动客户机程序

此时已经连接成功

3、开始聊天

此时已经可以实现通信功能。

五、总结

通过以上学习让我学会了什么是基于C/S模式的开发,同是在调试代码的过

成中也让我深深的体会到了调试的艰苦,因为有时候一个小小的错误可以调试一个下午都找不到错误在什么地方,最后当你找到的时候你会发现那是一个小的不能再小的错误,但是这么一个错误却浪费了你一个下午的时间。所以从这个地方我可以学到在编代码的过程中一定要注意细节,一定要细心。

还有其实细节只是我学到的一小部分,最重要的是,在编写一个软件的时候的前期规划,这个非常重要,现在我深有体会,因为之前的一些软件基本上都是先从代码下手,但是这次我从规划开始,先整天想好架构,然后具体细化,最后都编代码,整个过程还不到我以前编写一个软件所用的时间的一半。

成中也让我深深的体会到了调试的艰苦,因为有时候一个小小的错误可以调试一个下午都找不到错误在什么地方,最后当你找到的时候你会发现那是一个小的不能再小的错误,但是这么一个错误却浪费了你一个下午的时间。所以从这个地方我可以学到在编代码的过程中一定要注意细节,一定要细心。

还有其实细节只是我学到的一小部分,最重要的是,在编写一个软件的时候的前期规划,这个非常重要,现在我深有体会,因为之前的一些软件基本上都是先从代码下手,但是这次我从规划开始,先整天想好架构,然后具体细化,最后都编代码,整个过程还不到我以前编写一个软件所用的时间的一半。

本文来源:https://www.bwwdw.com/article/4vvr.html

Top