首先需要调用AfxSocketInit()函数来初始化我们的socket环境。
为了初始化sockets,我们需要调用AfxSocketInit()函数。它通常是在MFC中的InitInstance()函数中被调用的。如果我们用程序向导来创建socket程序的话,查看“use Windows Sockets”这个选项,然后选中它。它将会自动的为我们创建这个步骤了。(如果我们没有选中这个选项的话,我们也可以手动添加这些代码的。)这个函数的返回值显示这个函数的调用成功或失败。
BOOL CServerApp::InitInstance()
{....
if( AfxSocketInit() == FALSE)
{
AfxMessageBox("Sockets Could Not Be Initialized")
return FALSE
}
...
}
创建Server Sockets
为了创建一个Server Socket,我们需要声明一个CAyncSocket的变量或者我们自己定制的一个从AyncSocket或是Cscket继承来的类的类型的变量。然后调用Create()函数,同时指定监听的端口。这个函数的返回值显示这个函数的调用成功或失败。
UpdateData(TRUE)
m_sListener.Create(m_port)
if(m_sListener.Listen()==FALSE)
{
AfxMessageBox("Unable to Listen on that port,please try another port")
m_sListener.Close()
return
}
创建Client Sockets
为了创建Client socket类,我们需要声明一个CAyncSocket的变量或者我们自己定制的一个从AyncSocket或是Cscket继承来的类的类型的变量。然后调用Create()函数,同时指定监听的端口。这个函数的返回值显示这个函数的调用成功或失败。
m_sConnected.Create()
m_sConnected.Connect("server ip",port)
监听客户端的连接
创建了server socket以后,我们要进行监听。调用Listen()函数。这个函数的返回值显示这个函数的调用成功或失败。
if( m_sListener.Listen()== FALSE)
{
AfxMessageBox("Unable to Listen on that port,please try another port")
m_sListener.Close()
return
}
接受连接
连接请求要被接受accept,是用另外的socket,不是正在监听的socket。请参看代码。
void CXXXDlg::OnAccept()
{
CString strIP
UINT port
if(m_sListener.Accept(m_sConnected))
{
m_sConnected.GetSockName(strIP,port)//应该是GetPeerName,获取对方的IP和port
m_status="Client Connected,IP :"+ strIP
m_sConnected.Send("Connected To Server",strlen("Connected To Server"))
UpdateData(FALSE)
}
else
{
AfxMessageBox("Cannoot Accept Connection")
}
}
发送数据
数据放在一个buffer中或是结构体中,调用send()函数发送。
m_sConnected.Send(pBuf,iLen)
接受数据
调用receive()接受数据。
void CXXXrDlg::OnReceive()
{
char *pBuf =new char [1025]
CString strData
int iLen
iLen=m_sConnected.Receive(pBuf,1024)
if(iLen == SOCKET_ERROR)
{
AfxMessageBox("Could not Recieve")
}
else
{
pBuf[iLen]=NULL
strData=pBuf
m_recieveddata.Insert(m_recieveddata.GetLength(),strData)
//display in server
UpdateData(FALSE)
m_sConnected.Send(pBuf,iLen) //send the data back to the Client
delete pBuf
}
}
关闭连接
m_sConnected.ShutDown(0) 停止发送数据
m_sConnected.ShutDown(1) 停止接受数据
m_sConnected.ShutDown(2) 停止发送接受数据
m_sConnected.Close()
编写自己的socket类
在class view中选择添加一个新类,设置它的基类为CAsyncSocket,在类向导的帮助下添加如下的一些函数。
class MySocket : public CAsyncSocket
{ // Attributes
public:
// Operations
public:
MySocket()
virtual ~MySocket()
// Overrides
public:
void SetParentDlg(CDialog *pDlg)// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(MySocket)
public:
virtual void OnAccept(int nErrorCode)
virtual void OnClose(int nErrorCode)
virtual void OnConnect(int nErrorCode)
virtual void OnOutOfBandData(int nErrorCode)
virtual void OnReceive(int nErrorCode)
virtual void OnSend(int nErrorCode)
//}}AFX_VIRTUAL // Generated message map functions
//{{AFX_MSG(MySocket)
// NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG
protected:
private:
CDialog * m_pDlg
}
设置“Parent Dialog”
调用这个socket类的SetParentDlg函数,保证当socket事件发生的时候这个窗体能接收到。
m_sListener.SetParentDlg(this)
m_sConnected.SetParentDlg(this)
建立Socket 事件和窗体成员函数之间的联系
在这个窗体类中添加一些函数,比如void OnReceive()void OnClose()void OnAccept()void OnConnect()等,它们会在我们编写的的socket类中调用到。
void MySocket::OnAccept(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
if(nErrorCode==0)
{
((CServerDlg*)m_pDlg)->OnAccept()
}
CAsyncSocket::OnAccept(nErrorCode)
}
这个源码有个错误,是这个地方 char *buff[256]是256个指针,每个指针大小为4个字节,并且指向位置不确定,buff就是指向指针的指针,而不是指向空间的。应该为char buff[256]是256个字符空间 buff就是空间的首地址,也就指针,如果不改的话Receive( buff,256)就出错了。=(struct MEG*)buff
就是强制类型转换,将MEG指针 指向了 buff位置,利用MEG结构分组buff指向的内容。虽然buff是256但MEG大小之外的通过MEG指针访问不到。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)