UDP通讯实操,代码可直接使用

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;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值