《基于TCP的聊天程序设计与开发》实验指导一.实验目的通过设计网络协议及应用程序来加深理解网络各层的功能和机理,特别是对网络层、运输层、应用层的理解。独立编写基于TCP的网络应用程序,独立上机调试程序,掌握基于TCP的网络应用基本技术。培养独立思考问题、分析问题的能力和规范化工程设计的能力。综合运用所学的知识去解决实践中的应用问题,掌握实验技能。为以后的毕业设计与实际工作打下基础。二.实验方式与基本要求独立编写程序,独立上机调试程序,独立撰写实验报告三.实验基本步骤本试验采取分组进行协议设计,然后各自进行独立的完整的程序设计(包括概要设计与代码设计),然后互相通信。(如果设计正确,这组程序的任何一个都应与其它程序是互通的)。步骤1:程序总体结构:C/S结构。C与S分开。步骤2:服务器S程序基本构成S主进程初始化;例如voidCServerSocket::Start(){this-Create(1169);//创建端口进程this-Listen();}主进程进入监听;例如Listen();//开始监听重载虚函数OnAccept,响应客户请求voidCServerSocket::OnAccept(intnErrorCode){//TODO:Addyourspecializedcodehereand/orcallthebaseclassSOCKADDRSockAddr;inti=0;while(iSLAVEMAX){if(slave[i]==NULL){slave[i]=newCServerSlaveSocket(dlg,this,i);//创建子进程this-Accept(*slave[i],&SockAddr);//接受客户连接请求dlg-SetForegroundWindow();CStringidstr;idstr.Format(%d,i+1);//加上客户端编号slave[i]-Send(连接成功啦^-^,13);//发送连接成功消息给客户CStringc_IP;UINTc_Port;slave[i]-GetPeerName(c_IP,c_Port);//获取客户端IP和端口CStringstrPort;strPort.Format(%d,c_Port);charhostStr[50];//添加客户信息strcpy(hostStr,客户+idstr+[+c_IP+:+strPort+]);dlg-m_hostList.AddString(hostStr);//客户上线break;}i++;}if(i==SLAVEMAX){dlg-m_hostList.AddString(已超过最大连接数T_T);}CSocket::OnAccept(nErrorCode);}释放一个连接voidCServerSocket::DeleteSlaveSocket(intid){deleteslave[id];//////////////////////关闭子进程slave[id]=NULL;}从进程重载虚函数OnReceive,处理接收到的数据;例如voidCServerSlaveSocket::OnReceive(intnErrorCode){//TODO:Addyourspecializedcodehereand/orcallthebaseclasscharrbuf[256];intn;n=this-Receive(rbuf,256);//////////////////接受消息rbuf[n]='\0';this-GetPeerName(c_IP,c_Port);/////////获取对方IP,端口charbuf[512]={0};strcpy(buf,客户+uid+:);/////////////////////显示客户号CTimett;//////加上发送时间strcat(buf,tt.GetCurrentTime().Format(%H:%M:%S).GetBuffer(8));strcat(buf,\r\n);dlg-m_show+=buf;//////////////////strcpy(buf,);strcat(buf,rbuf);strcat(buf,\r\n);////////////////////////显示收到的信息dlg-m_show+=buf;//////////////////dlg-UpdateData(false);dlg-m_showCtrl.LineScroll(dlg-m_showCtrl.GetLineCount());//新消息总显示CSocket::OnReceive(nErrorCode);}由于要重载虚函数,所以,必须定义一个CSocket的派生类。从进程重载虚函数OnClose,释放连接,关闭进程voidCServerSlaveSocket::OnClose(intnErrorCode){//TODO:Addyourspecializedcodehereand/orcallthebaseclassm_using=false;//////////////删除连接客户/////////////////////dlg-m_hostList.DeleteString(dlg-m_hostList.FindString(-1,客户+uid));this-Close();//对应客户端关闭cs-DeleteSlaveSocket(m_id);//调用主进程的连接释放函数CSocket::OnClose(nErrorCode);}向客户发送信息;例如voidCServerDlg::Onsend(){//TODO:AddyourcontrolnotificationhandlercodehereUpdateData();charsbuf[256];m_send.GetWindowText(sbuf,256);//获取发送框的字符串m_send.SetWindowText();//编辑框置空m_send.SetFocus();/////焦点返回编辑框if(strlen(sbuf)!=0){if(m_hostList.GetCurSel()==0){///////发送给所有连接上的客户for(inti=0;iSLAVEMAX;i++){if(pserversocket-slave[i]!=NULL)pserversocket-slave[i]-SendMsg(sbuf);}}else///////////发送给选中的客户pserversocket-slave[m_hostList.GetCurSel()-1]-SendMsg(sbuf);charbuf[512]={0};strcpy(buf,自己:);CTimett;/////////////显示发送时间strcat(buf,tt.GetCurrentTime().Format(%H:%M:%S).GetBuffer(8));strcat(buf,\r\n);m_show+=buf;//////////////////strcpy(buf,);strcat(buf,sbuf);strcat(buf,\r\n);///////////显示发送内容m_show+=buf;////////////////////}UpdateData(false);m_showCtrl.LineScroll(m_showCtrl.GetLineCount());////////编辑框自动滚动}发送表情:voidCServerDlg::OnSendMood(){//TODO:AddyourcontrolnotificationhandlercodehereCStringstr,data;/////////////////////插入表情m_moodCtrl.GetLBText(m_moodCtrl.GetCurSel(),str);m_send.GetWindowText(data);m_send.SetWindowText(data+str);}清屏:voidCServerDlg::OnClearMsg()//清屏{//TODO:Addyourcontrolnotificationhandlercodeherem_show=_T();UpdateData(false);}步骤3:客户C程序基本构成创建TCP客户;voidCClientDlg::Onconnect(){//TODO:Addyourcontrolnotificationhandlercodeherecc-Create(0);////////创建端口if(cc-Connect(m_serverIP,1169))////////////////请求连接{m_send.EnableWindow(true);//允许发送m_connect.EnableWindow(false);//connectm_disconnect.EnableWindow(true);//disconnect}else{m_show+=_T(连接失败!T.T\r\n);///////////UpdateData(false);////////////m_showCtrl.LineScroll(m_showCtrl.GetLineCount());////////cc-Close();}return;}向服务器(m_serverIP,1169)发送连接请求;例如cc-Connect(m_serverIP,1169);断开连接:voidCClientDlg::Ondisconnect(){//TODO:Addyourcontrolnotificationhandlercodeherecc-Close();////////////////////////////////断开连接m_show+=_T(断开连接!-.-\r\n);///////////UpdateData(false);///////m_showCtrl.LineScroll(m_showCtrl.GetLineCount());//////////////////////////////////////////////////按钮不可用m_send.EnableWindow(false);//sendm_connect.EnableWindow(true);//connectm_disconnect.EnableWindow(false);//disconnect}向服务器发送信息;例如voidCClientDlg::Onsend(){//TODO:Addyourcontrolnotificationhandlercodeherecharsbuf[256];m_senddata.GetWindowText(sbuf,256);//获取发送框的字符串m_senddata.SetWindowText();//编辑框置空cc-Send(sbuf,strlen(sbuf));//发送信息m_senddata.SetFocus();/////焦点返回编辑框if(strlen(sbuf)!=0){//发送字符不为空charbuf[512]={0};strcpy(buf,自己:);//加上自己的标志CTimett;//加上发送时间strcat(buf,tt.GetCurrentTime().Format(%H:%M:%S).GetBuffer(8));strcat(buf,\r\n);m_show+=buf;strcpy(buf,);//显示自己发送的内容strcat(buf,sbuf);strcat(buf,_T(\r\n));m_show+=buf;UpdateData(false);m_showCtrl.LineScroll(m_showCtrl.GetLineCount());//新消息滚动}}发送表情:voi