为了弄这个通信程序,花了我好几晚的时间。没办法,没有学过c++,socket也一通半解。
?
环境:win7+vs2010
项目:c++的MFC项目
编码:一定不能使用unicode编码,不然会乱码(这个纠结了我好多时间)
?
看看效果:
?
初始化时,服务端和客户端的效果图:
?
服务端监听,客户端连接,如果IP和端口正确就可以连上
?
?
双方发送消息个过程,新消息在最上方:
?
看看Client 的关键代码:
*Dlg.cpp
class="cpp" name="code">void CTcpChatClntDlg::OnBnClickedButtonConnect() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); GetDlgItem(IDC_BUTTON_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); m_sConnectSocket.Create(); //创建客户端套接字 m_sConnectSocket.Connect(m_strServName, m_nServPort); //连接服务器 } void CTcpChatClntDlg::OnBnClickedButtonClose() { // TODO: 在此添加控件通知处理程序代码 OnClose(); } void CTcpChatClntDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 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); m_listSent.InsertString(0,m_strMsg); UpdateData(FALSE); } else { AfxMessageBox(LPCTSTR("信息发送错误!"), MB_OK|MB_ICONSTOP); } m_strMsg.Empty(); UpdateData(FALSE); } } void CTcpChatClntDlg::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; strReceived=pBuf; //m_listReceived.AddString(strReceived); m_listReceived.InsertString(0,strReceived); UpdateData(FALSE); } else{ AfxMessageBox(LPCTSTR("信息接收错误!"), MB_OK|MB_ICONSTOP); } } void CTcpChatClntDlg::OnConnect() { GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE); GetDlgItem(IDOK)->EnableWindow(TRUE); GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(TRUE); } void CTcpChatClntDlg::OnClose() { m_sConnectSocket.Close(); GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE); GetDlgItem(IDOK)->EnableWindow(FALSE); GetDlgItem(IDC_STATIC_MSG)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE); while(m_listSent.GetCount()!=0) m_listSent.DeleteString(0); while(m_listReceived.GetCount()!=0) m_listReceived.DeleteString(0); GetDlgItem(IDC_BUTTON_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); }
?
再看看Sever的关键代码:
*Dlg.cpp
void CTcpChatSvrDlg::OnBnClickedButtonListen() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); GetDlgItem(IDC_BUTTON_LISTEN)->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); m_sCListenSocket.Create(m_nServPort); m_sCListenSocket.Listen(); } void CTcpChatSvrDlg::OnBnClickedButtonClose() { // TODO: 在此添加控件通知处理程序代码 OnClose(); } void CTcpChatSvrDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 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); m_listSent.InsertString(0,m_strMsg); UpdateData(FALSE); } else { AfxMessageBox(LPCTSTR("信息发送错误!"), MB_OK|MB_ICONSTOP); } m_strMsg.Empty(); UpdateData(FALSE); } } void CTcpChatSvrDlg::OnClose(void) { m_listReceived.AddString(LPCTSTR("服务器收到了OnClose信息")); m_sConnectSocket.Close(); GetDlgItem(IDC_EDIT_MSG)->EnableWindow(FALSE); GetDlgItem(IDOK)->EnableWindow(FALSE); GetDlgItem(IDC_STATIC_MSG)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(FALSE); while(m_listSent.GetCount()!=0) m_listSent.DeleteString(0); while(m_listReceived.GetCount()!=0) m_listReceived.DeleteString(0); GetDlgItem(IDC_BUTTON_LISTEN)->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); } void CTcpChatSvrDlg::OnAccept(void) { m_listReceived.AddString(LPCTSTR("服务器收到了OnAccept消息")); m_sCListenSocket.Accept(m_sConnectSocket); GetDlgItem(IDC_EDIT_MSG)->EnableWindow(TRUE); GetDlgItem(IDOK)->EnableWindow(TRUE); GetDlgItem(IDC_STATIC_MSG)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON_CLOSE)->EnableWindow(TRUE); } void CTcpChatSvrDlg::OnReceive(void) { char *pBuf=new char[1025]; int nBufSize=1024; int nReceived; CString strReceived; //m_listReceived.AddString(LPCTSTR("服务器收到了OnReceive消息")); nReceived=m_sConnectSocket.Receive(pBuf,nBufSize); if(nReceived!=SOCKET_ERROR) { pBuf[nReceived]=NULL; strReceived=pBuf; //m_listReceived.AddString(strReceived); m_listReceived.InsertString(0,strReceived); UpdateData(FALSE); } else { AfxMessageBox(LPCTSTR("信息接收错误!"), MB_OK|MB_ICONSTOP); } }
?
好吧,其实还不是很懂的。不过浪费了这么多时间,还是记录下吧。
附件里有两个相应的EXE程序,有兴趣可以玩一下。不过要64位系统才行。