为了弄这个通信程序,花了我好几晚的时间。没办法,没有学过c++,socket也一通半解。
环境:win7+vs2010
项目:c++的MFC项目
编码:一定不能使用unicode编码,不然会乱码(这个纠结了我好多时间)
看看效果:
初始化时,服务端和客户端的效果图:
服务端监听,客户端连接,如果IP和端口正确就可以连上
双方发送消息个过程,新消息在最上方:
看看Client 的关键代码:
*Dlg.cpp
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位系统才行。