在使用WinSock MFC 类之前,必须为应用程序初始化WinSock 环境。
首先需要在StdAfx.h的MFC库头文件中,加入SOCKET的库
#include
然后在App()的InitInstance()中调用实例初始化函数AfxSocketInit()
if(!AfxSocketInit())
{
AfxMessageBox("Add Socket Failure");
return FALSE;
}
在Dlg()的OnInitDialog()中,调用函数InitSocket()初始化socket,创建线程
BOOL CDemopicDlg::OnInitDialog() { CDialog::OnInitDialog(); // 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(); // AfxMessageBox("Test"); //创建线程 PARAM *pPARAM = new PARAM; pPARAM->sock = sock2fd; HANDLE hThread = CreateThread(NULL,0,RecvProc,(LPVOID)pPARAM,0,NULL); CloseHandle(hThread); //关闭线程句柄
iFrameLen = 113; cSend = (char *)malloc(iFrameLen); memset(cSend,0,iFrameLen); return TRUE; // return TRUE unless you set the focus to a control }
|
//初始化两个SOCKET 1.作为客户端-发送数据,2.作为服务器-用于后台线程接收数据 BOOL CDemopicDlg::InitSocket() { //------------------------------------------------------ if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) == -1) //建立socket { AfxMessageBox("Socket Failed"); closesocket(sockfd); return FALSE; }
ServerAddress.sin_family = AF_INET; //ServerAddress.sin_addr.s_addr = inet_addr("10.11.6.111"); ServerAddress.sin_addr.s_addr = inet_addr("10.11.6.33"); ServerAddress.sin_port = htons(2233); //----------------------------------------------------
if((sock2fd = socket(AF_INET,SOCK_DGRAM,0)) == -1) //建立socket { AfxMessageBox("Socket Failed"); closesocket(sock2fd); return FALSE; } SOCKADDR_IN server_address; server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(3344);
if(bind(sock2fd,(SOCKADDR*)&server_address, sizeof(server_address)) == -1) { AfxMessageBox("bind"); closesocket(sock2fd); return FALSE; } //----------------------------------------------------- return TRUE; }
|
子线程函数RecvProc(),作为后台函数接收UDP数据包,在recvfrom处阻塞
DWORD WINAPI CDemopicDlg::RecvProc(LPVOID lpParameter) { //AfxMessageBox("Test");//作为服务器 SOCKET sock2fd = ((PARAM*)lpParameter)->sock;
int count = 0; int iFrameLen,iRecvLen; iFrameLen = 113; char *cRecv; cRecv = (char *)malloc(iFrameLen); memset(cRecv,0,iFrameLen);
SOCKADDR_IN client_address; int client_len = sizeof(SOCKADDR);
while(1) { iRecvLen = recvfrom(sock2fd,(char *)cRecv,iFrameLen,0, (SOCKADDR*)&client_address,&client_len); count++; if(iRecvLen == 0) { CString ttt; ttt.Format("%d",count); AfxMessageBox("后台线程接收到 "+ttt+" 字节"); //return TRUE; break; } } return TRUE; }
|
BUTTON函数OnSnd()中,调用打开对话框打开文件,并分包通过UDP发送
void CDemopicDlg::OnSnd() { // TODO: Add your control notification handler code here int i,j,count; count = 0; HANDLE hFile; DWORD dwByteRead; CString strFilter,fileName;
char* strText; strText = new char[113];
strFilter = "All Files(*.jpg)|*.jpg"; CFileDialog dlg(TRUE,NULL,NULL, OFN_EXPLORER|OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_FILEMUSTEXIST, strFilter); if(dlg.DoModal() == IDOK) { fileName = dlg.GetPathName(); hFile = CreateFile(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); do { ReadFile(hFile,strText,iFrameLen,&dwByteRead,NULL); cSend = strText; sendto(sockfd,(char *)cSend,dwByteRead,0,(SOCKADDR*)&ServerAddress,sizeof(SOCKADDR)); count++; for(i=0;i<20;i++) { for(j=0;j<10000;j++) {} } }while(dwByteRead != 0); } CloseHandle(hFile); }
|
注意点:
测试过程中,子线程的recvfrom没有阻塞,是因为sockfd标示要在Dlg类下
声明初始化,通过参数将标示传递给子线程,不能只在子线程中声明和定义。
阅读(2539) | 评论(0) | 转发(0) |