⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dlgudp.cpp

📁 周立功WinCE光盘资料
💻 CPP
字号:
// DLGUDP.cpp : implementation file
//

#include "stdafx.h"
#include "Magic2410.h"
#include "DLGUDP.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// DLGUDP dialog


DLGUDP::DLGUDP(CWnd* pParent /*=NULL*/)
	: CDialog(DLGUDP::IDD, pParent)
{
	//{{AFX_DATA_INIT(DLGUDP)
	m_RemoteHost = _T("");
	m_RemotePort = 0;
	m_SendStr = _T("Hello, This is 192.168.0.231.");
	m_LocalPort = 0;
	//}}AFX_DATA_INIT

	m_RemoteHost = "192.168.0.16";			/* 默认远程主机 IP 地址 */
	m_RemotePort = 1011;					/* 默认远程主机端口 */
	m_LocalPort = 1025;						/* 默认本机端口 */

	m_strRecDisp = _T("");					/* 请空接收区的显示 */ 
	m_UDPSocket = INVALID_SOCKET;			/* 本地 UDP Socket 无效 */
	m_ExitThreadEvent = NULL;				/* UDP 接收线程退出事件无效 */
	
	m_ButCloseSocket.EnableWindow(FALSE);	/* "关闭"按键无效 */	
	//UpdateData(FALSE);

}


void DLGUDP::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(DLGUDP)
	DDX_Control(pDX, IDC_OPEN, m_ButOpenSocket);
	DDX_Control(pDX, IDC_CLOSE_SOCKET, m_ButCloseSocket);
	DDX_Text(pDX, IDC_REMOTEHOST, m_RemoteHost);
	DDX_Text(pDX, IDC_REMOTEPORT, m_RemotePort);
	DDX_Text(pDX, IDC_SENDSTR, m_SendStr);
	DDX_Text(pDX, IDC_LOCALPORT, m_LocalPort);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(DLGUDP, CDialog)
	//{{AFX_MSG_MAP(DLGUDP)
	ON_BN_CLICKED(IDC_CLEAR_RECDISP, OnClearRecdisp)
	ON_BN_CLICKED(IDC_OPEN, OnOpen)
	ON_BN_CLICKED(IDC_CLOSE_SOCKET, OnCloseSocket)
	ON_BN_CLICKED(IDC_SEND, OnSend)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLGUDP message handlers

/*******************************************************************************************
函数名称: CSerialPortDlg::OnClearRec
描    述: "清除接收缓冲区" 按键单击事件代码
输入参数: 无
输出参数: 无
返    回: 无
********************************************************************************************/
void DLGUDP::OnClearRecdisp() 
{
	// TODO: Add your control notification handler code here
	m_strRecDisp = _T("");
	CEdit *pRecvStrEdit = (CEdit*)GetDlgItem(IDC_RECEIVESTR); /* 取得控件指针 */
														
	pRecvStrEdit->SetWindowText(m_strRecDisp);				  /* 在窗口显示出来 */
}

/*******************************************************************************************
函数名称: CUDPExampleDlg::OnOpen
描    述: "打开端口" 按键单击事件代码
输入参数: 无
输出参数: 无
返    回: 无
********************************************************************************************/
void DLGUDP::OnOpen() 
{
	// TODO: Add your control notification handler code here
	WSADATA wsa;
	DWORD IDThread;

	if (WSAStartup(MAKEWORD(1,1), &wsa) != 0)					/* WinSock 初始化 */
	{
		MessageBox(_T("加载套接字失败!"));
		return;
	}

	m_UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);		/* 创建UDP套接字 */
	if (m_UDPSocket == INVALID_SOCKET)
	{
		WSACleanup();
		MessageBox(_T("创建套接字失败!"));	
		return;
	}

	UpdateData(TRUE);
	SOCKADDR_IN localAddr;
	localAddr.sin_family = AF_INET;								/* 初始化本地sockaddr_in */
	localAddr.sin_port = htons(m_LocalPort);
	localAddr.sin_addr.s_addr = INADDR_ANY;

	// 绑定地址
	if (bind(m_UDPSocket, (sockaddr *)&localAddr, sizeof(localAddr)) != 0)
	{
		MessageBox(_T("绑定本地地址到Socket失败!"));
		return; 
	}

	DWORD ul = 1;
	ioctlsocket(m_UDPSocket, FIONBIO, &ul);						/* 设置非阻塞通信 */
	
	// 初始化远程 IP 地址及端口
	m_RemoteAddr.sin_family = AF_INET; 						
	m_RemoteAddr.sin_port = htons(m_RemotePort);				/* 设置远程端口 */

	char charRemoteHost[255];
	ZeroMemory(charRemoteHost, 255);
	int len = m_RemoteHost.GetLength(); 
	if (len > 255)
	{
		MessageBox(_T("输入远程IP长度超长!"));
		return;		
	}

	// 将 Unicode 字符串转换为字节
	LPTSTR pStr = m_RemoteHost.GetBuffer(len);
	WideCharToMultiByte(CP_ACP, 0, pStr, len, charRemoteHost, len, NULL, NULL);

	DWORD ipaddress = inet_addr(charRemoteHost);				/* 设置远程 IP 地址 */
 	if ((INADDR_NONE == ipaddress) || (0 == ipaddress))
	{
		MessageBox(_T("输入远程IP地址格式不正确!"));
		return;
	}
	m_RemoteAddr.sin_addr.s_addr = ipaddress;

	m_ExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);	/* 创建 UDP 接收线程退出事件 */

	// 创建 UDP 接收线程
	HANDLE hRecvThread = CreateThread(0, 0, UdpRecvTread, this, 0, &IDThread);
	if (hRecvThread == NULL) 
		MessageBox(_T("创建接收线程失败!"));

	CloseHandle(hRecvThread);

	m_ButCloseSocket.EnableWindow(TRUE);						/* "关闭"按键使能 */
	m_ButOpenSocket.EnableWindow(FALSE);						/* "打开"按键禁止 */
}

/*******************************************************************************************
函数名称: CUDPExampleDlg::OnCloseSocket
描    述: "关闭端口" 按键单击事件代码
输入参数: 无
输出参数: 无
返    回: 无
********************************************************************************************/
void DLGUDP::OnCloseSocket() 
{
	// TODO: Add your control notification handler code here
	if (m_ExitThreadEvent != NULL)
	{
		SetEvent(m_ExitThreadEvent);					/* 设置接收线程退出事件, 通知线程退出 */
		Sleep(1000);
		CloseHandle(m_ExitThreadEvent);					/* 关闭线程退出事件句柄 */
	}

	if (m_UDPSocket != INVALID_SOCKET)
	{	
		if (closesocket(m_UDPSocket) == SOCKET_ERROR)	/* 关闭 Socket */	
		{
			MessageBox(_T("关闭Socket失败!"));
			return;
		}
		m_UDPSocket = INVALID_SOCKET;

		if (WSACleanup() == SOCKET_ERROR)				/* 释放Socket资源 */
		{
			MessageBox(_T("释放Socket资源失败!"));
		}
	}

	m_ButCloseSocket.EnableWindow(FALSE);				/* "关闭"键禁止 */
	m_ButOpenSocket.EnableWindow(TRUE);					/* "打开"键使能 */
}

/*******************************************************************************************
函数名称: CSerialPortDlg::OnClearSend
描    述: "清除发送缓冲区" 按键单击事件代码
输入参数: 无
输出参数: 无
返    回: 无
********************************************************************************************/
void DLGUDP::OnSend() 
{
	// TODO: Add your control notification handler code here
	int nErrorCode;

	if (m_UDPSocket == NULL)
	{
		MessageBox(_T("本地 Socket 未打开!"));
		return;
	}

	UpdateData(TRUE);
 	int sendLen = m_SendStr.GetLength();				 /* 取得输入字符串长度 */
	char *psendbuff = new char[sendLen];

	for(int i = 0; i < sendLen;i++)
		psendbuff[i] = (char)m_SendStr.GetAt(i);		 /* 转换为单字节字符 */

	int len = sendto(m_UDPSocket, psendbuff, sendLen, 0, (sockaddr*)&m_RemoteAddr, sizeof(m_RemoteAddr));
	if (len == SOCKET_ERROR )
	{
		MessageBox(_T("UDP数据发送失败!"));
		nErrorCode = WSAGetLastError();
	}
	
	delete[] psendbuff;
}

/*******************************************************************************************
函数名称: CUDPExampleDlg::UdpRecvTread
描    述: UDP 接收线程
输入参数: LPVOID lparam: 线程参数,创建线程时传入
输出参数: 无
返    回: 0: 线程退出, 返回值没特殊含义
********************************************************************************************/
DWORD DLGUDP::UdpRecvTread(LPVOID lparam)
{
	fd_set fdRead;
	TIMEVAL aTime;
	aTime.tv_sec = 1;
	aTime.tv_usec = 0;
	SOCKADDR_IN tmpAddr;
	int iErrorCode;
	int ret;
	DLGUDP * pDlg = (DLGUDP*)lparam;

	while(TRUE)
	{
		if (WaitForSingleObject(pDlg->m_ExitThreadEvent, 0) == WAIT_OBJECT_0)
			break;

		FD_ZERO(&fdRead);
		FD_SET(pDlg->m_UDPSocket, &fdRead);
		ret = select(0, &fdRead, NULL, NULL, &aTime);
		if (ret == SOCKET_ERROR)
		{
			iErrorCode = WSAGetLastError();
			pDlg->OnUdpError(pDlg, iErrorCode);
			break;
		}

		if (ret > 0)
		{
			if (FD_ISSET(pDlg->m_UDPSocket, &fdRead))			/* 检查该socket是否是fdRead中的一员 */
			{
				tmpAddr.sin_family = AF_INET;
				tmpAddr.sin_port = htons(pDlg->m_RemoteAddr.sin_port);
				tmpAddr.sin_addr.s_addr = INADDR_ANY;
				
				char *recvBuf = new char[1024];
				int tmpRecvLen = sizeof(tmpAddr);
				int recvlen = recvfrom(pDlg->m_UDPSocket, recvBuf, 1024, 0, (SOCKADDR *)&tmpAddr, &tmpRecvLen);
				if ((recvlen == SOCKET_ERROR) || (recvlen == 0))
				{
					iErrorCode = WSAGetLastError();
					pDlg->OnUdpError(pDlg, iErrorCode);
					delete[] recvBuf;
					break;
				}
				else 
				{		
					pDlg->OnUdpRecv(pDlg, recvBuf, recvlen);			 /* 正确接收回调函数 */
					delete[] recvBuf;
				}

			}// end of if (FD_ISSET(pDlg->m_UDPSocket, &fdRead))

		}// end of if (ret > 0)
		
	}// end of while(TRUE)

	return 0;
}

void CALLBACK DLGUDP::OnUdpError(CWnd *pWnd, int nErrorCode)
{

}

/*******************************************************************************************
函数名称: CALLBACK CUDPExampleDlg::OnUdpRecv
描    述: UDP 接收数据成功回调函数
输入参数: 无
输出参数: 无
返    回: FALSE: 失败;    TRUE: 成功
********************************************************************************************/
void CALLBACK DLGUDP::OnUdpRecv(CWnd *pWnd, char *buf, int buflen)
{
	CString strTmp;

	DLGUDP * pDlg = (DLGUDP*)pWnd;
	CEdit *pRecvStrEdit = (CEdit*)pDlg->GetDlgItem(IDC_RECEIVESTR);
														/* 取得控件指针 */
	for (int i = 0; i < buflen; i++)
	{
		strTmp.Format(_T("%c"), *buf);
		pDlg->m_strRecDisp += strTmp;
		buf++;
	}

	pRecvStrEdit->SetWindowText(pDlg->m_strRecDisp);	/* 在窗口显示出来 */
}


/*******************************************************************************************
函数名称: CSerialPortDlg::OnDestroy
描    述: 对话框关闭事件处理函数
输入参数: 无
输出参数: 无
返    回: 无
********************************************************************************************/
void DLGUDP::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
	OnCloseSocket();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -