客户端部分:
Dlg.cpp:
// MFC_ChatDlg.cpp : 实现文件
//
/*
Process:
1.创建工程,允许windows库;
2.画界面,设定变量;
3.SetDlgItemText初始化IP,初始化端口值
4.CSocket类派生出 Mysocket,并重载receive send connect函数;大主类增加id的CString和一个MySocket变量
5.互相添加头文件
6.receive重载: 1)对话框指针
2)字符串,字符串长度,ircvd的一个int变量
3)※※※ircvd=receive(串,长)接收数据,socket_error排错
4)pbuf[ircvd]=NULL;;;通过 对话框指针 往 接收框 里 += 信息
5)更新窗口
7.connect重载: 1)对话框指针
2)获得参数code值,CString字符串用作马甲(其实可以没有)
3)※※※连上的话参数code值应该为0 排错
4)“连接成功!”,改变按钮,更新窗口
8.按钮 连接: 1)※※※AfxSocketInit 连接,成功==1,排错
2)※通过GetDlgItemText 取得ip的CString
3)初始化m_socket.m_hSocket = INVALID_SOCKET 为空
4)※※※Mysocket .creat一个,并判断socket_error排错
5)※※※.connect(IP字符串,PORT端口值)连接
9.按钮 发送: 1)※※※.Send(LPCTSTR(CS串),CS串.getlength) 发送数据,SOCKET_ERROR排错
2)显示在自己的屏幕上并更新
Error Reporder:
1.SetDlgItemText设置ipADRESS
参数要求(IPadress的ID, _T("127.0.0.1")); 后面的_T("")很重要!
2.如果出现 CID_DIALOG1 未定义
那么在出错位置上 加一行 #include “resource.h”
3.m_socket.Send(*char, ilen); //将信息 send出去,要把CString转化成char *,如下:
#include <atlbase.h> //char CString
USES_CONVERSION;
char *m_mesc = T2A(m_mes); //转化 char cstring
4.LPCTSTR不能用_T 因为_T只能将“”编程TCHAR类型,不能修改变量;而LPCTSTR可以!
5.socket等物质头文件关系要处理好,“未声明的标识符”就是这个错误!
*/
#include "stdafx.h"
#include "MFC_Chat.h"
#include "MFC_ChatDlg.h"
#include "afxdialogex.h"
#include <atlbase.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
///自动生成部分省略///
void CMFC_ChatDlg::OnBnClickedConnect()
{
// TODO: 在此添加控件通知处理程序代码
if (!AfxSocketInit()) //连接成功否?
{
AfxMessageBox(_T("IDP_SOCKETS_INIT_FAILED")); //翻译:连接失败
return;
}
GetDlgItemText(IDC_IPADDRESS1, m_ipstr); //dword类型的IP地址转化为字符串ipstr
m_socket.m_hSocket = INVALID_SOCKET; //并不理解
UpdateData(true);
BOOL flag = m_socket.Create(); //创建插座/嵌套字
if (!flag)
{
AfxMessageBox(_T("SOCKET ERROR"));
return;
}
m_socket.Connect(m_ipstr, m_port); //给出IP和端口进行连接
}
void CMFC_ChatDlg::OnBnClickedSend()
{
// TODO: 在此添加控件通知处理程序代码
int ilen;
int isent;
UpdateData(true);
if (m_mes != "")
{
ilen = m_mes.GetLength();
USES_CONVERSION;
char *m_mesc = T2A(m_mes); //转化 char cstring
isent = m_socket.Send(m_mesc, ilen); //将信息转化成LPCTSTR类型 send出去
if (isent == SOCKET_ERROR)
{
MessageBox(_T("连接失败,请重试!"));
}
else
{
m_recmes += "客户机:";
m_recmes += m_mes;
m_recmes += "\r\n";
UpdateData(false);
}
}
}
MySocket.cpp:
void MySocket::OnReceive(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类
//获取对话框指针
CMFC_ChatDlg *pDlg = (CMFC_ChatDlg*)AfxGetMainWnd(); //获取对话框指针!!!!
//往编辑框插入消息
char *pbuf = new char[4096];
int ibufsize = 4096;
int ircvd;
//CString strrecvd; //Unknown
//接收数据
memset(pbuf, 0, sizeof(pbuf));
ircvd = Receive(pbuf, ibufsize); //得到初始位置? 参数:字符串 + 长度
if (ircvd == SOCKET_ERROR)
{
pDlg->MessageBox(_T("SOCKET_ERROR")); //报错
}
else
{
pbuf[ircvd] = '\0'; //用作结尾\0
pDlg->m_recmes += "服务器:";
pDlg->m_recmes += pbuf;
pDlg->m_recmes += "\r\n";
pDlg->UpdateData(false); //更新hy
}
delete[] pbuf;
CAsyncSocket::OnReceive(nErrorCode);
}
void MySocket::OnConnect(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类
CMFC_ChatDlg * pDlg = (CMFC_ChatDlg*)AfxGetMainWnd();
int iResult = nErrorCode;
CString buffer;
//int namelen; //不知何为
if (iResult != 0) //连接失败
{
buffer.Format(_T("服务器连接失败。\r\n"));
pDlg->m_recmes += buffer;
}
else
{
//namelen = sizeof(sockaddr_in); //不知何为
buffer.Format(_T("成功连接到服务器"));
pDlg->m_recmes = buffer;
pDlg->m_recmes += pDlg->m_ipstr;
buffer.Format(_T(":%u \r\n", pDlg->m_port));
pDlg->m_recmes += buffer;
pDlg->GetDlgItem(IDC_SEND)->EnableWindow(true); //控制按钮
}
pDlg->UpdateData(false);
CAsyncSocket::OnConnect(nErrorCode);
}
服务端部分:
Dlg.cpp:
// MFC_ChatSerDlg.cpp : 实现文件
//
/*
Process:
1.创建工程,允许windows库;
2.画界面,设定变量;
3.SetDlgItemText初始化端口值
4.CSocket类派生出 Mysocket,并重载receive 函数;继续派生MySerSocket,重载accepted函数;大主类增加一个MySerSocket变量,MySerSocket增加MySocket变量
5.互相添加头文件
6.receive重载: 1)对话框指针
2)字符串,字符串长度,ircvd的一个int变量
3)爱咋咋地!
7.accepted重载:1)new一个MySocket嵌套字
2)Accept(新嵌套字)
3)执行嵌套字里的AsyncSelect(FD_READ)函数;
8.按钮 开服: 1)AfxSocketInit() 初始化嵌套字
2)m_sersocket.Create(m_port) 根据端口开放
3)m_sersocket.Listen(1) 开始监听
9.其他的发送什么的自便。
*/
#include "stdafx.h"
#include "MFC_ChatSer.h"
#include "MFC_ChatSerDlg.h"
#include "afxdialogex.h"
#include <atlbase.h> //char CString
//照例省略
void CMFC_ChatSerDlg::OnBnClickedListen()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
if (!AfxSocketInit())
{
AfxMessageBox(_T("IDP_SOCKET_INIT_FAILED"));
return;
}
BOOL flag = m_sersocket.Create(m_port);
if (!flag)
{
AfxMessageBox(_T("SOCKET_ERROR"));
return;
}
flag = m_sersocket.Listen(1); //开始监听
if (!flag)
{
AfxMessageBox(_T("SOCKET_ERROR"));
return;
}
SetDlgItemText(IDC_LISTEN, _T("正在监听"));
CMFC_ChatSerDlg *pDlg = (CMFC_ChatSerDlg*)AfxGetMainWnd();
pDlg->GetDlgItem(IDC_LISTEN)->EnableWindow(false);
}
void CMFC_ChatSerDlg::OnBnClickedSend()
{
// TODO: 在此添加控件通知处理程序代码
int ilen;
int isent;
UpdateData(true);
if (m_mes != "")
{
ilen = m_mes.GetLength();
USES_CONVERSION;
char *m_mesc = T2A(m_mes); //转化 char cstring
isent = m_sersocket.m_socket->Send(m_mesc, ilen);
if (isent == SOCKET_ERROR)
{
MessageBox(_T("连接失败,请重试!"));
}
else
{
m_recmes += "服务器:";
m_recmes += m_mes;
m_recmes += "\r\n";
UpdateData(false);
}
}
}
MySerSocket核心部分:
void CMySerSocket::OnAccept(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类
CMFC_ChatSerDlg *pDlg = (CMFC_ChatSerDlg*)AfxGetMainWnd();
//显示连接消息
pDlg->m_recmes += "客户端连入服务器";
pDlg->m_recmes += "\r\n";
pDlg->UpdateData(false);
pDlg->GetDlgItem(IDC_SEND)->EnableWindow(true);
MySocket * psocket = new MySocket();
if (Accept(*psocket))
{
psocket->AsyncSelect(FD_READ); //开启读取监听???
m_socket = psocket;
}
else
delete psocket;
CAsyncSocket::OnAccept(nErrorCode);
}
MySocket核心部分:
void MySocket::OnReceive(int nErrorCode)
{
// TODO: 在此添加专用代码和/或调用基类
//获取对话框指针
CMFC_ChatSerDlg *pDlg = (CMFC_ChatSerDlg*)AfxGetMainWnd(); //获取对话框指针!!!!
//往编辑框插入消息
char *pbuf = new char[4096];
int ibufsize = 4096;
int ircvd;
//CString strrecvd; //Unknown
//接收数据
ircvd = Receive(pbuf, ibufsize); //得到初始位置? 参数:字符串 + 长度
if (ircvd == SOCKET_ERROR)
{
pDlg->MessageBox(_T("SOCKET_ERROR")); //报错
}
else
{
pbuf[ircvd] = NULL;
pDlg->m_recmes += "客户端:";
pDlg->m_recmes += pbuf;
pDlg->m_recmes += "\r\n";
pDlg->UpdateData(false); //更新hy
}
delete[] pbuf;
CAsyncSocket::OnReceive(nErrorCode);
CAsyncSocket::OnReceive(nErrorCode);
}