上次写了个DOS平台下的,觉得功能比较弱,也步好用,这次作了个基于MFC的
闲话少说,开始写代码吧
1.先进一个基于对话框的MFC应用程序,对话框界面如下图所示
2.在stdafx.h中加入#include <Afxsock.h>,CApp类的InitInstance()中加入如下代码
if(!::AfxSocketInit())
{
AfxMessageBox("加载动态链接库失败!");
return false;
}
3.在主对话框类中加入一个私有变量SOCKET m_socket,加入一个成员函数
BOOL CComDlg::InitSocket()
{
m_socket = socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET == m_socket)
{
MessageBox("初始化套接字失败!");
return false;
}
SOCKADDR_IN sockAddr;
sockAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(7000);
int result;
result = ::bind(m_socket,(sockaddr*)&sockAddr,sizeof(sockaddr));
if(SOCKET_ERROR == result)
{
MessageBox("绑定套接字失败!");
::closesocket(m_socket);
return false;
}
return true;
}
4.在OnInitDialog()中加入一些代码,为了大家看清楚,整个的都拷上了
BOOL CComDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
InitSocket();
com *c = new com();
c->m_hWnd = m_hWnd;
c->m_socket = m_socket;
HANDLE hThread = ::CreateThread(NULL,0,Thread,(LPVOID)c,NULL,NULL);
::CloseHandle(hThread);
return TRUE; // return TRUE unless you set the focus to a control
}
红颜色的是加的代码
5.在RESOURCE.H中定义一个消息#define UM_RECEIVE WM_USER+1
在对话框类中加入相应的消息响应函数的声明和实现
声明:afx_msg void OnReceive(WPARAM wParam,LPARAM lParam);
实现:void CComDlg::OnReceive(WPARAM wParam,LPARAM lParam)
{
CString strRecv = (char*)lParam;
CString temp;
GetDlgItemText(IDC_EDIT_RECV,temp);
strRecv += "/r/n";
strRecv += temp;
SetDlgItemText(IDC_EDIT_RECV,strRecv);
}
6.因为在OnInitDialog()中创立了一个子线程,所以必须要在对话框类中加入一个静态的线程处理函数
声明:static DWORD WINAPI Thread(LPVOID lpParameter);
实现:DWORD WINAPI CComDlg::Thread(LPVOID lpParameter)
{
SOCKET m_socket = ((com*)lpParameter)->m_socket;
HWND m_hWnd = ((com*)lpParameter)->m_hWnd;
SOCKADDR_IN sockFrom;
int len = sizeof(sockaddr);
char recvBuf[100];
char tempBuf[100];
while(true)
{
::recvfrom(m_socket,recvBuf,100,0,(sockaddr*)&sockFrom,&len);
sprintf(tempBuf,"%s says: %s",inet_ntoa(sockFrom.sin_addr),recvBuf);
::PostMessage(m_hWnd,UM_RECEIVE,0,(LPARAM)tempBuf);
}
return 0;
}
7.添加BUTTOnDWORD WINAPI CComDlg::Thread(LPVOID lpParameter)
{
SOCKET m_socket = ((com*)lpParameter)->m_socket;
HWND m_hWnd = ((com*)lpParameter)->m_hWnd;
SOCKADDR_IN sockFrom;
int len = sizeof(sockaddr);
char recvBuf[100];
char tempBuf[100];
while(true)
{
::recvfrom(m_socket,recvBuf,100,0,(sockaddr*)&sockFrom,&len);
sprintf(tempBuf,"%s says: %s",inet_ntoa(sockFrom.sin_addr),recvBuf);
::PostMessage(m_hWnd,UM_RECEIVE,0,(LPARAM)tempBuf);
}
return 0;
}
7.添加BUTTON的单击消息相应函数
void CComDlg::OnButton1()
{
// TODO: Add your control notification handler code here
DWORD dwIP;
CString strSend;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
GetDlgItemText(IDC_EDIT_SEND,strSend);
SOCKADDR_IN sockAddr;
sockAddr.sin_addr.S_un.S_addr = htonl(dwIP);
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons(7000);
sendto(m_socket,strSend,strlen(strSend)+1,0,(sockaddr*)&sockAddr,sizeof(sockaddr));
SetDlgItemText(IDC_EDIT_SEND,"");
}
到这里,整个的代码架构终于告一段落了,大家可以做一下,搞清楚了之后,肯定大有收获啊,
累了,睡了!