异步(非阻塞)模式的学习

来源:互联网 发布:故宫攻略 知乎 编辑:程序博客网 时间:2024/06/07 08:20
一、开发了一个阻塞模式的通讯程序
    1、初始化socket
    WSADATA wsaData;
    WORD version=MAKEWORD(2,0);// Set small icon
    int ret=WSAStartup(version,&wsaData);
    if(ret!=0)
    {
        MessageBox("Init  Error");
        return FALSE;
    }

    2、启动一个监听
        if(m_hSocket)//如果已经创建,先关闭
    {
        closesocket(m_hSocket);
        m_hSocket=NULL;
    }
    else
    {
        m_hSocket=socket(AF_INET,SOCK_STREAM,0);
        ASSERT(m_hSocket);//
    }
   
    CString strError;
    m_hSocket;
    sockaddr_in addr;
    addr.sin_family=AF_INET;//表示在INT上通信
    addr.sin_addr.S_un.S_addr=INADDR_ANY;
    addr.sin_port=htons(m_iPort);
    int ret=0;
    int error=0;
   
    ret=bind(m_hSocket,(LPSOCKADDR)&addr,sizeof(addr));//绑定
    if(ret==SOCKET_ERROR)
    {
        strError.Format("Bind Error:%d ",error=WSAGetLastError());
        AfxMessageBox(strError);
        closesocket(m_hSocket);
        return;
    }
    ret=listen(m_hSocket,10);//监听
    if(ret==SOCKET_ERROR)
    {
        strError.Format("Listen Error:%d ",error=WSAGetLastError());
        AfxMessageBox(strError);
        closesocket(m_hSocket);
        return ;
    }
    else
    {
        m_cState.SetWindowText("服务端已经启动,等待连接中...");
    }
    AfxBeginThread(ListenThread,this);   

    3、监听线程
    UINT ListenThread(void *p)
{
      
    //准备接受请求
   
    while(1)
    {
        if(!pDlg->bAppend)
        {
            AfxEndThread(0);
            return 0;
        }
        CString strError;
        int error;
        ASSERT(pDlg!=NULL);
        struct   sockaddr_in   FAR addr;
        int   fromlen; 
        //SOCKET s=accept(pDlg->m_hSocket,NULL,NULL);
        fromlen=sizeof(addr);
        SOCKET s=accept(pDlg->m_hSocket,(LPSOCKADDR)&addr,&fromlen);
       
        CString strTmp;
        char tmpIP[3];
        itoa(addr.sin_addr.S_un.S_un_b.s_b1,tmpIP,10);
        strTmp=tmpIP;
        itoa(addr.sin_addr.S_un.S_un_b.s_b2,tmpIP,10);
        strTmp=strTmp+"."+tmpIP;
        itoa(addr.sin_addr.S_un.S_un_b.s_b3,tmpIP,10);
        strTmp=strTmp+"."+tmpIP;
        itoa(addr.sin_addr.S_un.S_un_b.s_b4,tmpIP,10);
        strTmp=strTmp+"."+tmpIP+" connection!";
        //pDlg->m_List.AddString(strTmp);
        pDlg->WriteLog(strTmp);
        if(s==SOCKET_ERROR)
        {
            if(pDlg->bAppend)
            {
                strError.Format("Accept Error:%d ",error=WSAGetLastError());
                AfxMessageBox(strError);
                closesocket(pDlg->m_hSocket);
                return -1;
            }
            else
            {
                break;
            }
        }
        pDlg->RevFile(s);
    }
    return 0;
}

4、文件接收函数
void CBaGJSocketDlg::RevFile(const SOCKET& s)
{
   
    char buffer[1024];
    char temp[1024];
    memset(buffer,0,sizeof(buffer));
    memset(temp,0,sizeof(temp));
    int rcv = recv(s,buffer, 1024, 0);
    for (int i=0; buffer[i]!='*'; i++)
    {
        temp[i] = buffer[i];
    }
   

    temp[i++] = '/0';
    CString strFileName = temp;//得到文件名
    strcpy(temp, buffer + i);
    long lFileSize = atol(temp);//文件大小;
    m_progress.SetRange32(0, lFileSize);    //设置进度条范围
    m_progress.SetStep(1);    //设置进度条步长
    m_progress.ShowWindow(SW_SHOW);
    m_cState.SetWindowText("文件正在接收....");
    CString tmpStr;
    tmpStr="recieve file:"+strFileName;
    WriteLog(tmpStr);
        m_strFilePath="c://"+strFileName;
        //进度条操作//   
        //接受并保存文件。
        CFile file(m_strFilePath, CFile::modeCreate | CFile::modeWrite);
        long iTemp = 0;
        while (1)
        {
            rcv = recv(s, buffer, 1024, 0);
            if (rcv == 0)
            {
                break;
            }
            file.Write(buffer, rcv);
            iTemp += rcv;
            m_progress.ShowWindow(SW_SHOW);
            m_progress.SetPos(iTemp);
        }
        file.Close();
        if (iTemp != lFileSize)
        {
            AfxMessageBox("文件接收失败!");
        }

    m_cState.SetWindowText("文件接收成功!");
    shutdown(s,SD_BOTH);
    closesocket(s);
   
}

5、日志函数,显示在list中
void CBaGJSocketDlg::WriteLog(LPCTSTR LogText)
{
    CString tmp;
    CTime curTime=CTime::GetCurrentTime();
    tmp=curTime.Format("%Y-%m-%d %H:%M:%S");
    tmp=tmp+":"+LogText;
    m_List.AddString(tmp);
}

这段代码也不是自有“产权”,也是根据一个Demo改写的
原创粉丝点击