首先需要调用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)
}
是从WinMain()函数开始的,不过MFC的WinMain()函数在MFC的类库里,而不在你编的程序中!MFC的执行次序也就是windows应用程序的执行次序嘛,从WinMain()入口,然后是定义窗口类,注册窗口类,显示窗口,消息循环~~~~
WinMain()跟main()函数一样,是用run time自己调用的。C++程序启动的顺序是这样的:
1. 构造全局对象。在MFC程序里,theApp就是全局对象。因为theApp的类型是CTestApp,所以CTestApp的构造函数会被调用
2. 调用main()或者WinMain()。如果是MFC程序,会默认提供一个WinMain()函数的实现,你不需要自己另外写。如果你自己另外写一个WinMain(),会引起Link Error。
以上两步都是C++ Run Time做的,不需要你自己写什么代码。你可以认为C++就是这么规定的。
补充:
是,有代码去调用它。但是这些代码不需要你来写,对你来讲也没有什么意义。这些代码属于runtime
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)