当前位置:文档之家› 基于TCP的聊天程序设计与开发

基于TCP的聊天程序设计与开发

基于TCP 的聊天程序设计与开发》实验指导一.实验目的通过设计网络协议及应用程序来加深理解网络各层的功能和机理,特别是对网络层、运输层、应用层的理解。

独立编写基于TCP的网络应用程序,独立上机调试程序,掌握基于TCP的网络应用基本技术。

培养独立思考问题、分析问题的能力和规范化工程设计的能力。

综合运用所学的知识去解决实践中的应用问题,掌握实验技能。

为以后的毕业设计与实际工作打下基础。

二.实验方式与基本要求独立编写程序,独立上机调试程序,独立撰写实验报告三.实验基本步骤本试验采取分组进行协议设计,然后各自进行独立的完整的程序设计 (包括概要设计与代码设计) ,然后互相通信。

(如果设计正确,这组程序的任何一个都应与其它程序是互通的) 。

步骤1:程序总体结构:C/S 结构。

C 与S 分开。

步骤2:服务器S 程序基本构成S 主进程初始化;例如void CServerSocket::Start() { this->Create(1169); // 创建端口进程this->Listen();} 主进程进入监听;例如Listen();// 开始监听重载虚函数OnAccept,响应客户请求void CServerSocket::OnAccept(int nErrorCode){// TODO: Add your specialized code here and/or call the base class SOCKADDRSockAddr;int i=0;while(i<SLAVEMAX){ if(slave[i]==NULL){ slave[i] = newCServerSlaveSocket(dlg,this,i);// 创建子进程this->Accept(*slave[i],&SockAddr);//接受客户连接请求dlg->SetForegroundWindow();CString idstr;idstr.Format("%d",i+1);// 加上客户端编号slave[i]->Send(”连接成功啦A-A",13);//发送连接成功消息给客户CString c_IP;UINT c_Port;slave[i]->GetPeerName(c_IP,c_Port);// 获取客户端IP 和端口CString strPort;strPort.Format( "%d",c_Port);char hostStr[50];〃添加客户信息strcpy(hostStr,"客户"+idstr+"["+c_IP+":"+strPort+"]");dlg->m_hostList.AddString(hostStr);// 客户上线break;}i++;}if(i==SLA VEMAX){dlg->m_hostList.AddString(" 已超过最大连接数T_T");}CSocket::OnAccept(nErrorCode);}释放一个连接void CServerSocket::DeleteSlaveSocket(int id){delete slave[id];////////////////////// 关闭子进程slave[id] = NULL;}从进程重载虚函数OnReceive,处理接收到的数据;例如void CServerSlaveSocket::OnReceive(int nErrorCode){// TODO: Add your specialized code here and/or call the base class char rbuf[256];int n;n = this->Receive(rbuf,256);////////////////// 接受消息rbuf[n] = '\0';this->GetPeerName(c_IP ,c_Port);///////// 获取对方IP ,端口char buf[512]={0};strcpy(buf,"客户"+uid+": ");///////////////////// 显示客户号CTime tt; //////加上发送时间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 ,释放连接,关闭进程void CServerSlaveSocket::OnClose(int nErrorCode) {// TODO: Add your specialized code here and/or call the base class m_using = false;////////////// 删除连接客户/////////////////////dlg->m_hostList.DeleteString(dlg->m_hostList.FindString(-1," 客户"+uid));this->Close();// 对应客户端关闭cs->DeleteSlaveSocket(m_id);// 调用主进程的连接释放函数CSocket::OnClose(nErrorCode);}向客户发送信息;例如void CServerDlg::Onsend(){// TODO: Add your control notification handler code hereUpdateData();char sbuf[256];m_se nd.GetWi ndowText(sbuf,256);〃获取发送框的字符串m_send.SetWindowText(""); //编辑框置空m_send.SetFocus(); /////焦点返回编辑框if(strlen(sbuf)!=0){if(m_hostList.GetCurSel()==0){/////// 发送给所有连接上的客户for(int i=0;i<SLAVEMAX;i++){if(pserversocket->slave[i]!=NULL)pserversocket->slave[i]->SendMsg(sbuf);}}else /////////// 发送给选中的客户pserversocket->slave[m_hostList.GetCurSel()-1]->SendMsg(sbuf);char buf[512]={0};strcpy(buf,"自己:”);CTime tt; ///////////// 显示发送时间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());//////// 编辑框自动滚动}发送表情:void CServerDlg::OnSendMood(){// TODO: Add your control notification handler code hereCString str,data;///////////////////// 插入表情m_moodCtrl.GetLBText(m_moodCtrl.GetCurSel(),str); m_send.GetWindowText(data);m_send.SetWindowText(data+str);}清屏:void CServerDlg::OnClearMsg() // 清屏{// TODO: Add your control notification handler code here m_show=_T("");UpdateData(false);}步骤3:客户C 程序基本构成创建TCP 客户;void CClientDlg::Onconnect(){// TODO: Add your control notification handler code here cc->Create(0); //////// 创建端口if(cc->Connect(m_serverIP,1169))//////////////// 请求连接{m_send.EnableWindow(true); //允许发送m_connect.EnableWindow(false); //connect m_disconnect.EnableWindow(true); //disconnect }else{m_show += _T(" 连接失败!T.T\r\n");/////////// UpdateData(false);////////////m_showCtrl.LineScroll(m_showCtrl.GetLineCount());//////// cc->Close();}return;}向服务器(m_serverlP,1169)发送连接请求;例如cc->Connect(m_serverI P , 1 1 69) ;断开连接:void CClientDlg::Ondisconnect(){// TODO: Add your control notification handler code herecc->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 }向服务器发送信息;例如void CClientDlg::Onsend(){// TODO: Add your control notification handler code herechar sbuf[256];m_senddata.GetWindowText(sbuf,256);// 获取发送框的字符串m_senddata.SetWindowText(""); // 编辑框置空cc->Send(sbuf,strlen(sbuf)); // 发送信息m_senddata.SetFocus();///// 焦点返回编辑框if(strlen(sbuf)!=0) { //发送字符不为空char buf[512]={0};strcpy(buf," 自己: "); //加上自己的标志CTime tt; // 加上发送时间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());// 新消息滚动}} 发送表情:void CClientDlg::OnMood(){// TODO: Add your control notification handler code here CString str,data;///////////////////// 插入表情m_moodCtrl.GetLBText(m_moodCtrl.GetCurSel(),str);m_senddata.GetWindowText(data);m_senddata.SetWindowText(data+str);}重载虚函数OnReceive,处理接收到的数据;例如void CClientSocket::OnReceive(int nErrorCode) // 接收消息{// TODO: Add your specialized code here and/or call the base class char rbuf[256];int n;n = this->Receive(rbuf,256); // 获取收到的消息字符串rbuf[n]='\0';char buf[512]={0};strcpy(buf,"服务器端:”);CTime tt; // 加上发送时间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);}清屏:void CClientDlg::OnClearMsg() /////////////////// 清屏{// TODO: Add your control notification handler code here m_show = _T("");UpdateData(false);}四.实验结果客户端:服务器端:连接:■消息通信:多用户连接:断开连接:五. 实验问题多用户连接时,到达最大连接数时,程序会出现问题,已连接的客户断开后,无法再连接上。

相关主题