Socket udp用WAAsyncSelect传递消息方式

用UDP做局域网的套接字通讯,有很多优势,

但是网上很多介绍都是关于TCP监听机制,用UDP的 都是透过创建线程或者While循环或者SetTimmer

如下例子是透过WAAsyncSelect来监听是否有FD_READ,FD_CLOSE等事件;



1.包含头文件

#include <afxsock.h>            // MFC 套接字扩展
2.定义全局变量和自定义函数:

SOCKET m_Socket;//定义SOCKET套接字
BOOL Read(void);//自定义一个接收信息的函数
BOOL Send(CString sIP, u_short nPort, CString sSendData);//自定义 发送函数
3.创建一个按钮,按钮的响应函数里进行创建套接字等动作:

	m_Socket = INVALID_SOCKET;
if ((m_Socket=socket(AF_INET, SOCK_DGRAM,0))== INVALID_SOCKET)
{ 
AfxMessageBox("创建套接字失败!"); 
} 
SOCKADDR_IN m_saAddr;
u_short m_nPort = 20049;// 端口号
ZeroMemory(&m_saAddr, sizeof(m_saAddr));
m_saAddr.sin_family  = AF_INET;
m_saAddr.sin_port= htons(m_nPort); // 如果此值为0,系统将随机选择一个未被使用的端口号
m_saAddr.sin_addr.s_addr = INADDR_ANY;  // 填入本机IP地址
if (bind(m_Socket, (LPSOCKADDR) &m_saAddr, sizeof(m_saAddr)) == SOCKET_ERROR)
{
AfxMessageBox("绑定端口失败!");
}
if (WSAAsyncSelect(m_Socket, m_hWnd, WM_NETWORK_EVENT, FD_READ|FD_CLOSE|) == SOCKET_ERROR)
{
AfxMessageBox("注册网络事件失败!");
} 

4.自定义Windows消息的响应函数:

	afx_msg LRESULT OnNetworkEvent(WPARAM wParam, LPARAM lParam);
5.自定义一个消息链接:
BEGIN_MESSAGE_MAP(CMFCApplication4Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication4Dlg::OnBnClickedButton1)
	ON_MESSAGE(WM_NETWORK_EVENT,&C****Dlg::OnNetworkEvent)
END_MESSAGE_MAP()

6.响应消息的自定义函数的定义:


LRESULT CMFCApplication4Dlg::OnNetworkEvent(WPARAM wParam, LPARAM lParam)
{
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
	Read();
	if(!Send("127.0.0.1",6000,"600"))
	AfxMessageBox("No");
break;
case FD_ACCEPT:
	
break;
}
return 0L;
}
7.自定义的函数:

BOOL Read(void)
{
int nBytesRead;
int nBufferLength;
int nEnd;
int nSpaceRemaining;
char chIncomingDataBuffer[4096];
SOCKADDR_IN m_saFromAddr;
int nLenght = sizeof(m_saFromAddr);
ZeroMemory(&m_saFromAddr, sizeof(SOCKADDR_IN));
nEnd = 0;
nBufferLength = sizeof(chIncomingDataBuffer);
nSpaceRemaining = sizeof(chIncomingDataBuffer);
nSpaceRemaining -= nEnd;

nBytesRead = recvfrom(m_Socket, (LPSTR) (chIncomingDataBuffer + nEnd), nSpaceRemaining, 0, (LPSOCKADDR) &m_saFromAddr, &nLenght);
nEnd += nBytesRead;
if (nBytesRead == SOCKET_ERROR)
{
AfxMessageBox("读取数据出错!");
return FALSE;
}
// IP地址:inet_ntoa(m_saFromAddr.sin_addr);
// 端口号:ntohs(m_saFromAddr.sin_port);
chIncomingDataBuffer[nEnd] = '\0';
if (lstrlen(chIncomingDataBuffer) != 0) 
{
AfxMessageBox(chIncomingDataBuffer);
}
return TRUE;
}
BOOL Send(CString sIP, u_short nPort, CString sSendData)
{
	sSendData+='\0';
DWORD dwIP;
SOCKADDR_IN saAddr;
if (m_Socket == INVALID_SOCKET)
{
AfxMessageBox("套接字不可用!");
return FALSE;
}
if ((dwIP = inet_addr(sIP)) == INADDR_NONE)
{
AfxMessageBox("无法获取目标IP!");
return FALSE;
}
saAddr.sin_family  = AF_INET;
saAddr.sin_port= htons(nPort);
saAddr.sin_addr.s_addr = dwIP;
if (sendto(m_Socket, sSendData, sSendData.GetLength(), 0, (LPSOCKADDR) &saAddr, sizeof(saAddr)) == SOCKET_ERROR)
{
AfxMessageBox("发送数据失败!");
return FALSE;
}
return TRUE;
} 










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值