Chinaunix首页 | 论坛 | 博客
  • 博客访问: 773714
  • 博文数量: 37
  • 博客积分: 575
  • 博客等级: 中士
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-12 10:43
个人简介

活到老,学到老!

文章分类

全部博文(37)

文章存档

2019年(4)

2018年(4)

2015年(1)

2014年(14)

2011年(1)

2010年(13)

我的朋友

分类: C/C++

2010-05-13 15:29:16

在使用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类下

声明初始化,通过参数将标示传递给子线程,不能只在子线程中声明和定义。

阅读(2421) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~