1.创建WSA
if (WSAStartup(WINSOCK_VERSION,&wsaData))//WSADATA wsaData;
{
MessageBeep(MB_ICONSTOP);
MessageBox("Winsock could not be initialized!", AfxGetAppName(), MB_OK|MB_ICONSTOP);
WSACleanup();
return(FALSE);
}
2.创建套接字
m_sSend=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP/*0*/); //yongliang
m_sRecv=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP/*0*/);
3.套接字绑定并进行消息映射
addrSend.sin_family=AF_INET;//SOCKADDR_IN addrSend;
addrSend.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr(m_chLocalIp);
addrSend.sin_port=htons(/*SENDPORT*/m_SendPort);
if (bind(m_sSend,(LPSOCKADDR)&addrSend,sizeof(addrSend))== SOCKET_ERROR)
{
if(WSAGetLastError() == WSAEADDRINUSE)
{
Phone_ReportWinsockErr("当前发送端口被占用,无法绑定");//Phone_ReportWinsockErr为自定义函数,可用MessagBox代替
}
else
{
Phone_ReportWinsockErr("Cannot bind SendPort");
}
return FALSE;
}
addrRecv.sin_family=AF_INET;
addrRecv.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr(m_chLocalIp);
addrRecv.sin_port=htons(/*RECEIVEPORT*/m_ReceivePort);//m_ReceivePort端口号
if (bind(m_sRecv,(LPSOCKADDR)&addrRecv,sizeof(addrRecv))==SOCKET_ERROR)
{
if(WSAGetLastError() == WSAEADDRINUSE)
{
Phone_ReportWinsockErr("当前接收端口被占用,无法绑定");
}
else
{
Phone_ReportWinsockErr("Cannot bind ReceivePort");
}
return FALSE;
}
int iError=WSAAsyncSelect(m_sRecv,m_hWnd/*this->GetSafeHwnd()*/,WM_READREADY,FD_READ|FD_CLOSE);//用于将网络信息映射为窗口消息函数
4.创建窗口消息映射函数
ON_MESSAGE(WM_READREADY,OnReadReady)//具体的OnReadReady函数依据需求编写带码。
窗口消息需要不断的接受经UDP发送来的消息,接受信息的函数为recvfrom;具体格式如下:
iRecievedNum=recvfrom(m_sRecv,chRecv,BLOCK,0,(LPSOCKADDR)&m_RemoteAddr,&tmp);
5.主被叫相互发送连接请求消息
发送消息内容/格式几乎一样,只是SOCKET IN参数不同。
SOCKADDR_IN to;
to.sin_family=AF_INET;
to.sin_port=htons(/*RECEIVEPORT*/m_ReceivePort);
to.sin_addr.S_un.S_addr=m_RemoteIP;//inet_addr("210.32.151.247");
//char* str=(char*)malloc(64);
char chQuery[64];
sprintf(chQuery,"PHONEBUSY %s CONNECT %s",m_CLocalIP,m_CRemoteIP);//消息格式自定义/自解析
int iError=sendto(m_sSend,chQuery,sizeof(chQuery),0,(LPSOCKADDR)&to,sizeof(to));
至此,两者即可实现通讯,再定义的窗口消息内处理相应的消息即可。
6.结束通讯
可以通过发送特定消息,在窗口消息内对消息进行解码后处理即可。
7.结束进程
结束进程时要清理建立的WSA;
if(m_sSend)
closesocket(m_sSend);
if(m_sRecv)
closesocket(m_sRecv);
if ( 0 != WSACleanup() )
{
CString chMsgBuffer;
chMsgBuffer.Format(_T("Winsock error %d."), WSAGetLastError());
//char chMsgBuffer[100];
//wsprintf(chMsgBuffer, "Winsock error %d.", WSAGetLastError());
//MessageBeep(MB_ICONSTOP);
MessageBox(chMsgBuffer, AfxGetAppName(), MB_OK|MB_ICONSTOP);
//return FALSE;
}