上次寫了個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,"");
}
到這裏,整個的代碼架構終於告一段落了,大家可以做一下,搞清楚了之後,肯定大有收穫啊,
累了,睡了!