,在CChatDlg类中加入对 按钮Listen的处理函数如下:
void CChatDlg::OnListen()
{
pClientSocket = new CClientSocket(this);
if(pClientSocket != NULL)
{
if(!pClientSocket->Create(SNMP_SOCKET_PORT, SOCK_DGRAM))
AfxMessageBox("Can not create ClientSocket !");
else
::EnableWindow(GetDlgItem(IDC_LISTEN)-> m_hWnd,FALSE);
}
else
{
AfxMessageBox("Can not new ClientSocket !");
}
}
注意:SNMP_SOCKET_PORT应设为161。 然后,在CClientSocket中加入 虚函数OnReceive的实作内容:
void CClientSocket::OnReceive(int nErrorCode)
{
CSocket::OnReceive(nErrorCode);
unsigned char tmp[MAXTMPSIZE];
//MAXTMPSIZE是自定义宏,可为1024;
int i;
int RecNum;
UINT ClientPort;
CString ClientAddress;
if(m_bFirst)
{
m_bFirst = false;
RecNum = ReceiveFrom(tmp, MAXTMPSIZE, ClientAddress, ClientPort);
if(RecNum > 0)
{
TRACE("Received from client, %d bytes :\n", RecNum);
for(i=0; i<RecNum; i++)
{
if(i%10==0)
TRACE("\n%5d,", tmp[i]);
else
TRACE("%5d,", tmp[i]);
}
TRACE("\n\n");
pDlg->CreateServerSocket(ClientAddress, ClientPort);
pDlg->Send(true, tmp, RecNum);
}
else
AfxMessageBox("Error: fail to Receive from client the first time!");
}
else
{
RecNum = Receive(tmp, MAXTMPSIZE);
if(RecNum > 0)
{
TRACE("Received from client, %d bytes :\n", RecNum);
for(i=0; i<RecNum; i++)
{
if(i%10==0)
TRACE("\n%5d,", tmp[i]);
else
TRACE("%5d,", tmp[i]);
}
TRACE("\n\n");
pDlg->Send(true, tmp, RecNum);
}
else
AfxMessageBox("Error: fail to Receive from client!");
}
if(RecNum <= 0)
{
AfxMessageBox("Error: fail to Receive from client !");
return;
}
}
本段程序的大概意思是:如果本程序首次收到来自网管程序的UDP包,则要记录下它的Socket端口号和IP 地址,这是本程序最关键的地方之一。这样做的原因是:网管通讯开始时一般是由网管程序首先发出SNMP 请求包,所以要先响应网管程序;另一目的是由此获得事先未知的网管
程序侦听的Socket端口号和IP地址,然后让CChatDlg由此创建CServerSocket。随后调用CChatDlg的Send函数将收到的UDP包转发给交换机,并在Output窗口按每行10个的格式显示出收到的数据。
上段
程序中CChatDlg的Send和CreateServerSocket函数的内容如下:
void CChatDlg::CreateServerSocket (CString address, UINT port)
{
m_ClientAddress = address;
m_ClientPort = port;
pServerSocket = new CServerSocket(this);
if(pServerSocket != NULL)
{
if(!pServerSocket->Create(m_ClientPort, SOCK_DGRAM))
AfxMessageBox("Can not creat