您的当前位置:首页网络编程技术课程设计报告

网络编程技术课程设计报告

2020-02-07 来源:小侦探旅游网


课程设计(论文)

题 目 名 称 聊天软件的开发 课 程 名 称 网络编程技术课程设计 学 生 姓 名 学 号 系 、专 业 指 导 教 师

2016年 5月 22日

摘 要

聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了“进入聊室”、“发送聊天信息”和“离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发。本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。

关键词:Visual C++,客户端-服务器(C/S)结构,简单聊天软件

目 录

1 前言 ...................................................... 错误!未定义书签。 2 需求分析................................................... 错误!未定义书签。

任务和要求 ............................................... 错误!未定义书签。 应实现的功能 ............................................. 错误!未定义书签。 界面及控件变量 ........................................... 错误!未定义书签。 3 分析和设计 ................................................. 错误!未定义书签。

系统分析及设计思路 ....................................... 错误!未定义书签。 主要控件的功能 ........................................... 错误!未定义书签。 程序流程图 ............................................... 错误!未定义书签。 (一)流程运行框架 ....................................... 错误!未定义书签。 (二)服务端 ............................................. 错误!未定义书签。 (三)客户端 ............................................. 错误!未定义书签。 4 具体代码实现 ............................................... 错误!未定义书签。

服务器................................................... 错误!未定义书签。 设计结论 ................................................. 错误!未定义书签。 参考文献..................................................... 错误!未定义书签。 致 谢 ...................................................... 错误!未定义书签。

1 前言

本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。聊天软件由客户端和服务器两部分构成,服务器充当“中转者”的职能,客户端将自己的消息首先发给服务器,服务器再根据需要将它们转发给其他客户端。聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了”进入聊天室”,”发送聊天信息”和”离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发,服务器根据接收到的不同消息格式做出不同的处理。

2 需求分析

任务和要求

本次课程设计内容任务是简单群聊软件的设计与实现。三人以上为一组,其中一个同学为群聊软件的服务器端,另外同学为群聊软件客户端,服务器开启后公布其IP地址和端口号,客户端用服务器的IP地址和端口号进行登录,观察服务器与客户端的显示的结果,然后由客户端发送群聊消息,观察服务器与各客户端的显示结果。

具体要求如下:

1.采用客户端——服务器(C/S)结构,聊天室软件由客户端和服务器两部分构成,即创建两个工程,服务器(SelfRoom)和客户端(SelfChat)。

2.服务器的对话框界面应具有聊天室IP、端口、开启、关闭、聊天室动态、在线用户等基本内容,而客户端的对话框界面应具有昵称、聊天室IP、端口、登录、离开、聊天记录、在线好友等基本内容,添加相应的成员函数,使程序能正常运行。

3.聊天程序采用UDP协议,基于UDP协议的聊天过程中遵守一种约定,这种约定规定了“进入或离开聊天室”和“发送聊天信息”数据传输格式,服务器作为“中转者”通过接收客户端不同的数据格式来进行判断消息发送者的欲进行的操作,然后对消息进行处理后再进行转发。

应实现的功能

此次课程设计内容是群聊软件的设计与实现,采用MFC类编程。下面介绍一下服务器和客户端所实现的功能。

服务器的界面中有管理员、聊天室IP、端口、聊天室动态和在线用户列表,还有“开启”、“关闭”、“退出”按钮。运行服务器时,先进行管理员、聊天室IP、端口的配置,点击“开启”按钮后,聊天室动态的文本框里会显现“聊天室开启成功”等消息以及当时得时间,便可等待成员的加入;当有成员加入时,也会有相应的提示信息,用户列表也会及时更新;当客户端发来消息,服务器会将此消息转发给每一个成员;当列表中的所有成员都离开时,服务器可点击“关闭”,即关闭聊天室。

客户端的界面有您的昵称、聊天室IP、端口、聊天文本框、在线好友列表,还有“进入”、“离开”、“发送”按钮。运行客户端时,先进行昵称、聊天室IP、端口的配置,点击“进入”按钮,与服务器进行了连接;连接成功后,可发送聊天消息点击“发送”就能将消息发送到服务器,让服务器进行处理,发送的信息会显示在聊天框里,每条消息前面还附有发送消息时的时间,在线好友列表中会显示已进入聊天室的成员,可以与他们进行群聊,由于这只是简单的群聊软件,所以只能发送文字信息,不具备发送表情、文件等高级功能;当有成员加入或离开聊天室时,聊天框内会有提示信息,在线好友列表也会即时更新;当客户端想离开时,可以点击“离开”按钮,即可退出聊天室。

界面及控件变量

(一)服务器

运行界面,如图。

图 服务器界面图

(二)客户端

运行界面,如图。

图客户端运行界面图

3 分析和设计

系统分析及设计思路

本次聊天软件采用MFC编程,需要创建2个工程,分别是客户端工程SelfChat和服务器工程SelfRoom,由于本次软件需用到套接字类,所以在创建工程的时候需要选择“Windows Sockets”复选框,并都基于基本对话框。在制作服务器的时候需要添加两个基于CSocket的套接字:CClientSocket(用来监听)和CServerSocket(为每个加入聊天室的客户端生成一个相应的对象与之通信),另外添加一个C++结构体tagHeader(用于客户端和服务器之间辨识消息类型的)。在制作客户端时添加一个基于CSocket的套接字类CClientSocket(用于连接服务器通信),和服务器一样要添加一个C++结构体tagHeader。

整个流程中的事件时序如下:

1. 服务器配置管理员、聊天室IP以及端口后,单击“开启”按钮,此时服务器主动调用Listen()开始监听。

2. 客户端配置昵称、聊天室IP以及端口后,单击“进入”按钮,此时客户端向服务器发起连接Connect()请求,若请求被接收,则紧接着发送会话消息。

3. 服务器的CServerSocket类接收请求并触发OnAccept()事件,该事件过程创建对应请求方客户端的CClientSocket类对象并添加到Socket队列。

4. 更多成员客户端加入时,服务器重复步骤3。

5. 某个成员(客户端)要发送聊天消息时,在发送信息文本框中编辑文字,单击“发送”按钮向服务器发出消息。

6. 某个成员(客户端)发来的消息到达服务器,触发服务器Socket队列中对应该客户端CClientSocket类对象的OnReceive()事件,对发来的消息进行处理。

7. 服务器上对应该客户端的CClientSocket类对象,根据消息头tagHeader结构中的type字段辨别消息类型:若type=LOGIN_IO,则表示有新成员加入,用广播方式通知所有其他成员客户端,并调用服务器UpdateUser()更新服务器用户列表;若type=SEND_MESSAGE,则表示这只是普通的成员的发言信息,直接广播转发该消息就可以了。

8. 服务器发出的消息到达客户端,触发客户端本地OnReceive()事件,客户端本地Socket根据消息头tagHeader结构中的type字段辨识消息类型:若type=LOGIN_IO,则表示有新成员加入或已有聊天成员下线退出,于是调用客户端UpdateUser()函数更新本地用户列表;若type=SEND_MESSAGE,则表示这是聊天室中其他成员发来的消息,调用GetMsgFromRoom()函数接收之后显示在客户

端的屏幕上。

9. 某个成员要下线时,单击“离开”按钮,关闭本地Socket。

10. 一旦某成员退出,关闭了自己客户端程序的本地Socket,就会触发其在服务器上的Socket队列中对应的CClientSocket类对象的Onclose()事件,由CClientSocket类对象发消息通知其他成员有人退出,并调用UpdateUser()更新服务器用户列表。

11. 当最后一个成员离开聊天室后,管理员可单击“关闭”按钮关闭服务器。

主要控件的功能

服务器主要控件的功能见表,客户端的主要控件功能见表。 控件 “管理员”文本框 IP控件 “端口”文本框 “聊天室动态”只读文本框 “用户在线”列表框 “开启”按钮 “关闭”按钮 “退出”按钮 配置管理员名称 配置聊天室IP 配置聊天室端口 显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息 显示已进入聊天室的成员 开启聊天室 关闭聊天室 退出 表服务器的主要控件的功能

功能

控件 “您的昵称”文本框 IP控件 “端口”文本框 “在线好友”列表框 “聊天”只读文本框 “发送”信息文本框 “发送”按钮 配置昵称 配置聊天室IP 配置聊天室端口 显示已进入聊天室的成员 显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息 编辑要发送的消息 将消息发送出去 功能 “进入”按钮 “离开”按钮 “退出”按钮 进入聊天室 离开聊天室 退出 表客户端的主要控件功能

程序流程图

(一)流程运行框架

开始开始定义、创建数据报套接字CSeverSocket定义、创建数据报套接字CClientSocket单击“开始”按钮单击“进入”按钮向服务器发起连接Connect()请求创建CClientSocket类添加到Socket()队列请求是否被接收?是CServerSocket类接收请求并触发OnAccept()事件创建CClientSocket并添加到Socket队列否触发OnReceive()事件判断消息头tagHeader结构的type字段的类型?是tupe =SEND_MESSAGE直接广播转发该消息否tupe =LOGIN_IO调用UpdateUser()是否有人要发言?是客户端人数是否满足?是是否要离开?广播通知所有客户端成员,更新服务器用户列表是成员发言,编辑文字,点击“发送”按钮触发服务器本地OnReceive()事件单击“离开”按钮,关闭本地Socket触发CClientSocket类对象的OnClose()事件调用UpdateUser()更新本地用户列表调用GetMsgFromRoom()接收后显示在屏幕上所有人离开后,管理员单击“关闭”按钮结束图 流程运行框架程序流程图

(二)服务端

1.服务器“开启”按钮程序流程图 如图

开始UpdateData;刷新界面,获得用户输入m_pSocket=new CServerSocket;创建套接字BYTEn Fild[4];CString sIP;创建IP的结构和字节CString t=time.Format(\"%Y-%m-%d\");m_MessageList.ReplaceSel(\"日期:\"+t+\"\\r\\n\");t=time.Format(\"%H:%M:%S\"); 获得聊天室开启的时刻信息theApp.m_strName=m_strName; 记录管理员名ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]);获取管理员配置的IPsIP.Format(\"%d.%d.%d.%d\ld[0],nFild[1],nFild[2],nFild[3]);获得网络字节的IP地址CTime time=CTime::GetCurrentTime();获取当前时间sIP.IsEmpty()是否IP不为空?否m_MessageList.ReplaceSel(t+\"管理员\"+theApp.m_strName+\"开放聊天室\\r\\n\");设置管理员的管理信息否m_pSocket->Create(atoi(sPort),1,sIP)套接字和指定信息匹配情况?是m_MessageList.SetWindowTextA(\"\");m_MessageList.ReplaceSel(\"聊天室开启成功!\\r\\n\");CString t=time.Format(\"%Y-%m-%d\");m_MessageList.ReplaceSel(\"日期:\"+t+\"\\r\\n\");t=time.Format(\"%H:%M:%S\");获得聊天室开启的时刻信息theApp.m_strName=m_strName; //记录管理员名AfxMessageBox(\"请配置聊天室IP!\");是否if(sPort.IsEmpty())是否端口号存在?是AfxMessageBox(\"请配置要开放的窗口!\");m_MessageList.ReplaceSel(t+\"管理员\"+theApp.m_strName+\"开放聊天室\\r\\n\");否m_Admin.EnableWindow(false);ServerIP.EnableWindow(false);ServerPort.EnableWindow(false);m_Start.EnableWindow(false);m_Stop.EnableWindow(true);m_Exit.EnableWindow(false);开启聊天室,首先创建用于监听的套接字m_pSocket->Listen()监听是否开始?m_pSocket->Create(atoi(sPort),1,sIP)是否创建套接字?是否是m_MessageList.ReplaceSel(\"等待成员加入…\\r\\n\");现在暂时还无人加入聊天,因此在线用户列表中仅管理员一人m_UserList.ResetContent();m_UserList.AddString(theApp.m_strName+\"(管理员)\");this->SetWindowTextA(\"管理员:\"+m_strName+\"-SelfRoom\");m_MessageList.SetWindowTextA(\"\");m_MessageList.ReplaceSel(\"聊天室开启成功!\\r\\n\")结束图 服务器“开启”按钮程序流程图

2.客户端发送的消息到达服务器后,触发服务器Socket队列对应该客户端给的套接字的OnReceive()事件 如图

开始charcharbuff[sizeof(Header)];memset(buff,0,sizeof(buff));Receive(buff,sizeof(buff));首先接收消息的头部并定义Header *header=(Header*)buff1;int length=header->len;char type=header->type;解析头部内容否Curr->m_strName==m_strName用户名是新添成员名?是curr->Send((char*)&head_history,sizeof(Header)); curr->Send(m_dlgServer->m_history,m_dlgServer->m_history.GetLength());向新成员发欢迎消息否type==LOGIN_IO头部类型为LOGIN_IO,表示是新成员的加入。判断是否?是charbuff[1000];memset(buff,0,sizeof(buff));Receive(buff,sizeof(buff));继续接收这条信息的数据部分(新成员名)根据要求,生成通知信息m_dlgServer->UpdateUser(this);更新用户列表curr->Send((char*)&head,sizeof(Header));curr->Send(strTemp,strTemp.GetLength());向聊天室中其他的老成员发送通知信息,告知有新成员加入CString strTemp=t+\" \"+CString(buff)+\"进入聊天室/\\r\\n\";p_Edit->ReplaceSel(strTemp);m_strName=buff;将新加入成员的用户名登记在服务器对应的Socket中type==SEND_MESSAGE;消息类型为聊天消息?否Header head_history;head_history.type=SEND_MESSAGE;生成“欢迎”信息是接收消息,按照要求改变格式m_dlgServer->m_history+=m_strName+”欢迎您加入!”;否CClientSocket *curr=NULL;POSITIONpos=clist->GetHeadPosition();创建用户套接字,获取链表clist表头位置pos!=NULL是否向聊天室内所有成员转发聊天信息内容?是否pos!=NULL判断表头是否为空?curr=(CClientSocket*)clist->GetNext(pos);curr->Send((char*)header,sizeof(Header));curr->Send(str,str.GetLength());向聊天室内所有成员转发聊天信息内容是curr=(CClientSocket*)clist->GetNext(pos);找到表中所有的用户结束图 服务器OnReceive()事件程序流程图

3.服务器UpdateUser函数过程流程图 如图

开始m_UserList.ResetContent();m_UserList.AddString(theApp.m_strName+\"管理员\");首先添加管理员用户CStringuser_info;user_info=theApp.m_strName+\"(管理员)\"+\"&\";添加管理员信息pSocket!=NULL是服务套接字不为空?否Headerhead;head.type=LOGIN_IO;head.len=user_info.GetLength(); 登陆消息结构体POSITION po=pSocket->clist->GetHeadPosition();链表clist的表头位置po!=NULL表不为空?是否CClientSocket*pSock=NULL;POSITION pos=pSocket->clist->GetHeadPosition();重新定义pos!=NULL链表不为空?是否pSock=(CClientSocket*)pSocket->clist->GetNext(po);pSock->Send((char*)&head,sizeof(Header)); pSock->Send((LPCTSTR)user_info,user_info.GetLength());将最新的用户列表转发给各个用户pSock=(CClientSocket *)pSocket->clist->GetNext(pos);m_UserList.AddString(pSock->m_strName);user_info+=(pSock->m_strName+\"&\");逐个添加已记录的用户名结束图 服务器UpdateUser函数程序流程图

4.服务器OnClose()事件流程图 如图

开始(客户端“离开”按钮触发服务端上Socket队列中对应的CClientSocket类的对象的OnClose()事件)POSITION pos=clist->Find(this);要删除的用户名在链表中的位置pos!=NULL)链表不为空?pos!=NULL?链表不为空?是Clist->RemoveAt(pos);移除服务器Socket队列中的套接字CString t=time.Format(\"%H:%M:%S\");CString strTemp=t+\" \"+this->m_strName+\"离开聊天室\\r\\n\";在聊天室动态框里显示成员离开信息及时间p_Edit->ReplaceSel(strTemp);Header head;head.type=SEND_MESSAGE;head.len=strTemp.GetLength();CClientSocket*curr=NULL;定义信息的格式m_dlgServer->UpdateUser(this); 更新服务器列表否是curr=(CClientSocket*)clist->GetNext(pos);curr->Send((char*)&head,sizeof(Header));curr->Send(strTemp,strTemp.GetLength());告知其他成员此成员已离开POSITION pos=clist->GetHEeadPosition();否CSocket::OnClose(nErrorCode);结束语句结束图 服务器OnClose()事件流程图

(三)客户端

1.客户端“进入”按钮事件流程图 如图

开始UpdateData();m_pSocket=newCClientSocket;m_pSocket->GetDlg(this);获取主界面指针BYTE nFild[4];CString sip;ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]);sip.Format(\"%d.%d.%d.%d\ld[2],nFild[3]);获取用户输入的服务器IP是AfxMessageBox(\"网络创建错误!!!\");m_pSocket->Close();重新创建否!m_pSocket->Connect(sip,atoi(strport))服务器没有连接?否m_strName.IsEmpty()昵称是否为空?是是AfxMessageBox(\"连接服务器失败!!!\");m_pSocket->Close();重新连接服务器否设置界面m_pSocket->Send((char*)&head,sizeof(Header));m_pSocket->Send(m_strName,m_strName.GetLength());发送会话消息AfxMessageBox(\"给自己起个昵称吧!\");sip.IsEmpty()聊天室是否为空?是AfxMessageBox(\"请指定IP地址!\");否strport.IsEmpty()端口号是否为空?是AfxMessageBox(\"请指定连接端口!\");否theApp.m_strName=m_strName;m_MessageList.SetWindowTextA(\"\");this->SetWindowTextA(m_strName+\"-SelfChat\");标题栏实时动态显示用户名!m_pSocket->Create()是否没有创建网络?结束图 客户端“进入”按钮事件程序流程图

2.客户端“发送”按钮事件流程图 如图

m_strMessage==\" \"消息为空?AfxMessageBox(\"不能发送空消息\");m_EditWords.SetFocus();开始UpdateData();刷新数据Header head;head.type=SEND_MESSAGE;这是聊天内容,消息头类型为SEND_MESSAGEhead.len=m_strMessage.GetLength();m_pSocket->Send((char*)&head,sizeof(Header))定义消息头的长度、格式等信息m_pSocket->Send(m_strMessage,m_strMessage.GetLength())是否发送聊天消息?是m_strMessage=\"\";UpdateData(FALSE);m_EditWords.SetFocus()发送聊天消息AfxMessageBox(\"网络传输错误!\")否结束图 客户端“发送”按钮流程流程图

3.客户端本地OnReceive()事件流程图 如图

否开始char buff[sizeof(Header)];定义接收缓冲区memset(buff1,0,sizeof(buff));Receive(buff1,sizeof(buff));收到服务器发来的消息Header*header=(Header*)buff1;定义信息头结构体 int length=header->len;char type=header->type;解析信息头部type==SEND_MESSAGE消息类型为聊天消息?是chatDlg->GetMsgFromRoom()直接接收chatDlg->GetMsgFromRoom()直接接收否type==LOGIN_IO 消息类型为登陆消息?是chatDlg->UpdateUser()在线用户情况有变化,同步更新用户表结束图 客户端本地OnReceive()事件流程图

4.客户端的GetMsgFromRoom()和UpdateUser()函数流程图 如图

否i++否Cstring user_info=buff;Cstring array[100];int b=0;定义所有用户的信息格式int i=0;赋初值 开始GetMsgFromRoom()函数Charbuff[1000];memset(buff,0,sizeof(buff));m_pSocket->Receive(buff,sizeof(buff));接收信息CstringstraTemp=buff;strTemp+=”\\r\\n”;m_MessageList.ReplaceSel(strTemp);直接显示在界面上即可Charbuff[1000];memset(buff,0,sizeof(buff));m_pSocket->Receive(buff,sizeof(buff));接收到最新的在线用户名单UpdateUser()函数ij5.客户端的“离开”函数流程图 如图.

结束开始m_pSocket是否存在?是m_pSocket->Close();delete m_pSocket;离开时要记得关闭、销毁Socketm_UserList.ResetContent();m_MessageList.ReplaceSel(“你已经退出了,谢谢光顾!”);this->SetWindowTextA(“聊天室客户端-SelfChat”);聊天室客户端给予相应的离开消息界面设计否图 客户端的“离开”函数流程图

4 具体代码实现

服务器

1.单击“开启”按钮,添加函数:

void CSelfRoomDlg::OnButton1() {

d.%d.%d\",nFild[0],nFild[1],nFild[2],nFild[3]);

CTime time=CTime::GetCurrentTime(); 户端用户发送消息到达服务器的OnReceive()事件:

void CClientSocket::OnReceive(int nErrorCode) {

务器检测到新成员加入,调用UpdateUser()函数更新用户列表: void CSelfRoomDlg::UpdateUser(CClientSocket *pSocket) { ();

+\"管理员\"); CString user_info; user_info=+\"(管理员)\"+\"&\"; if(pSocket!=NULL) {

CClientSocket *pSock=NULL;

POSITION pos=pSocket->clist->GetHeadPosition(); while(pos!=NULL) {

pSock=(CClientSocket *)pSocket->clist->GetNext(pos); (pSock->m_strName);

user_info+=(pSock->m_strName+\"&\"); }

Header head; =LOGIN_IO; =();

POSITION po=pSocket->clist->GetHeadPosition(); while(po!=NULL) {

pSock=(CClientSocket *)pSocket->clist->GetNext(po); pSock->Send((char *)&head,sizeof(Header)); pSock->Send((LPCTSTR)user_info,()); } } }

4.成员退出,关闭自己的Socket,触发服务器的OnClose()事件:

void CClientSocket::OnClose(int nErrorCode) {

户端“进入”按钮的事件过程代码如下: void CSelfChatDlg::OnButton1() {

d.%d.%d\

发送”按钮的事件处理代码如下:

void CSelfChatDlg::OnButton3() { 户端本地OnReceive()事件过程:

void CClientSocket::OnReceive(int nErrorCode) {

于接受两类不同消息分别调用两个处理GetMsgFromRoom()和UpdateUser()函数,代码如下:

BOOL CSelfChatDlg::GetMsgFromRoom() {

char buff[1000];

memset(buff,0,sizeof(buff));

m_pSocket->Receive(buff,sizeof(buff));户端“离开”按钮的事件过程代码如下:

void CSelfChatDlg::OnButton2() { if(m_pSocket){ m_pSocket->Close();

delete m_pSocket;管理员“开启”聊天室:对服务器中的管理员、聊天室IP、端口进行相应的配置,点击“开启”按钮。

3.成员“进入”聊天室:对客户端的昵称、聊天室IP、端口进行相应配置,点击“进入”,成员进入后,自己的聊天框内会有欢迎信息,其他成员的聊天框、聊天室动态中会显示成员加入信息。如图成员jyh“进入”聊天室。

4.成员“发送”消息:在客户端的聊天编辑框中输入要发的消息,点击“发送”,即可将消息发送出去,消息会在自己、其他成员的聊天框以及聊天室动态中显示。如图 成员jyh“发送”消息。

5.成员“离开”聊天室:点击客户端中的“离开”,即可离开聊天室,自己的聊天框内会有退出的提示消息,离开的提示信息会显示在其他成员的聊天框,并且其他成员和聊天室的在线好友和在线用户列表会更新。

6.管理员“关闭”聊天室:所有在线用户都离开聊天室时,可点击服务器中的“关闭”。

设计结论

做了两周的课程设计,我个人觉得本次收获是很大的。(

自己写)

参考文献

[1]孙飞显. TCP/IP网络编程技术与实例[M]. 北京:国防工业出版社,. [2]罗莉琴,詹祖桥.Windows网络编程[M].北京:人民邮电出版社,. [3]郑阿奇.Visual C++网络编程教程[M].北京:电子工业出版社,2013.6. [4]马争鸣.TCP/IP原理与应用[M].北京:治金出版社,.

[5]宋春花,吕进来.C++程序设计[M].北京:人民邮电出版社,.

致 谢

两周的网络编程课程设计很快就要变成了过去式了,在这段时间里,我收获了很多,很感谢学校提供了这么一次实战的机会让我们更好地学习知识。

在此,我非常感谢的是我们的指导老师***老师。他是一位认真负责的好老师,对我们的爱都表现在和我们玩笑和打闹中。但其实我们是知道的,他真的是一位很好的老师。在得知是我们的知道老师以后,他在第一时间询问了我们的课表,准备为我们安排开会的时间。是一个没课的早上,他让我们到了办公室开会,还叮嘱我们务必认真对待此次课程设计,要分工明确、不清楚的可以咨询他、需要资料的可以请教他等等,我们真的是被老师的尽职尽责所动容。他还及时为我们解决问题,让我们在自我编程的基础上学习到更多的知识。感谢许老师!当然,也不能忘记我们的任课老师***老师,他一直以身作则,还为我们做好实验的模板,就是为了我们能更好的理解。老师们给了我们很大的支持和鼓励,才使得课程设计得以顺利的完成,在此真心感谢能遇见这么好的老师们!

其次,感谢这一次认真的队友——***、***、***同学。***和***同学真的是很努力,两个人非常认真地对自己的工作进行交流,主动咨询老师,我也是在这个过程中学习了很多原本不能学到的东西,受益匪浅。***同学的主要工作是文档内容,她的基础知识没有那么好,而且在课程设计期间,她的计算机损坏了,我们帮助她完成了部分的文档工作,但是,她依旧还是很努力地做着自己的能做的工作,不清楚的地方也会问我们,在这个团队中贡献着自己的力量。我觉得和这几位同学作为一个团队的伙伴是一件很幸运的事。感谢你们!

最后,我要感谢的是我自己。感谢自己在遇到困难时的不放弃,感谢自己的认真和执着,感谢自己在这次课程设计中学习到了很多不会的东西,认识到了自己的不足和缺点。“耐得住寂寞,守得住花开。”希望自己今后能学习到更多的东西,变得更加优秀!

因篇幅问题不能全部显示,请点此查看更多更全内容