mfc socket 编程的流程是怎么样的?

mfc socket 编程的流程是怎么样的?,第1张

初始化socket

首先需要调用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


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11119521.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存