MFC tcp socket来传文件

来源:互联网 发布:温州网络问政 编辑:程序博客网 时间:2024/06/16 07:00

   近来没有太多的时间来详细记录周围的东西,今日就记录一波MFC 用socket来传文件,毕竟没用过mfc的socket,认真搞了一天,收获还行,并整理出了一个Demo。下面就把关键点贴出


客户端:

//----------------------------发送文件的线程------------------------------UINT Thread_Send(LPVOID lpParam){    CClientDlg *dlg=(CClientDlg *)lpParam;    (dlg->GetDlgItem(IDC_BTN_SEND))->EnableWindow(FALSE);    CSocket Clientsock; //definition socket.    if(!AfxSocketInit())    {        AfxMessageBox("afxSocketInit Failed");    }    CString IP="";    dlg->GetDlgItem(IDC_EDIT_IP)->GetWindowText(IP);    CString strport="6070";    dlg->GetDlgItem(IDC_EDIT_PORT)->GetWindowText(strport);    int port=atoi(strport);    //创建    if(!Clientsock.Socket())    {        CString str;        str.Format(_T("Socket创建失败: %d"),GetLastError());        (dlg->GetDlgItem(IDC_BTN_SEND))->EnableWindow(TRUE);        AfxMessageBox(str);    }    //连接    //  if(!Clientsock.Connect(_T("127.0.0.1"),8088))    if(!Clientsock.Connect(IP,port))    {        CString str;        str.Format(_T("Socket连接失败: %d"),GetLastError());        (dlg->GetDlgItem(IDC_BTN_SEND))->EnableWindow(TRUE);        AfxMessageBox(str);    }    else    {        WIN32_FIND_DATA FindFileData;        CString strPathName; //定义用来保存发送文件路径的CString对象        dlg->GetDlgItemText(IDC_EDIT_FILENAME,strPathName);        FindClose(FindFirstFile(strPathName,&FindFileData));        Clientsock.Send(&FindFileData,sizeof(WIN32_FIND_DATA));        CFile file;        if(!file.Open(strPathName,CFile::modeRead|CFile::typeBinary))        {            AfxMessageBox(_T("文件不存在"));            (dlg->GetDlgItem(IDC_BTN_SEND))->EnableWindow(TRUE);            return 1;        }        //发送        UINT nSize = 0;        UINT nSend = 0;        char szBuff[2048];        while(nSize<FindFileData.nFileSizeLow)        {            memset(szBuff,0x00,2048);            nSend = file.Read(szBuff,2048);            Clientsock.Send(szBuff,nSend);//发送数据            nSize += nSend;        }        file.Close();        Clientsock.Close();        (dlg->GetDlgItem(IDC_BTN_SEND))->EnableWindow(TRUE);    }    return 0;}

步骤:一、创建CSocket 对象
   二、AfxSocketInit();//在哪个线程就在哪个线程里调用这个
   三、调用Socket()方法,来创建socket句柄
   四、调用Connect()方法,来连接服务器,参数IP,PORT
   五、Connect成功就发送数据呗,
   六、WIN32_FIND_DATA这个结构体来保存要发送文件的属性,如文件名,文件大小
   七、Clientsock.Send(&FindFileData,sizeof(WIN32_FIND_DATA));先把文件属性发送到服务器端
   八、以二进制方式打开文件
   九、开一个2kb的缓存
   十、读取文件缓存,再发送到服务器,如此循环即将文件发送完毕!


服务器端:

//----------------------------监听文件的线程------------------------------bool m_exit = false;unsigned int StartServer(LPVOID lParam){    if (!AfxSocketInit())    {        AfxMessageBox("InitFailed");        return 1;    }    m_exit = false;    CServerDlg *aDlg = (CServerDlg *)lParam;    CString strPort;    aDlg->GetDlgItemText(IDC_EDIT_PORT, strPort);    UINT nPort = atoi(strPort);//获取端口号    //socket------------------------------------------------    CSocket aSocket, serverSocket;    if (!aSocket.Socket())    {        char szError[256] = {0};        sprintf(szError, "Create Faild: %d", GetLastError());        AfxMessageBox(szError);        return 1;     }    BOOL bOptVal = TRUE;    int bOptLen = sizeof(BOOL);    aSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET);    if (!aSocket.Bind(nPort))    {        char szError[256] = {0};        sprintf(szError, "Bind Faild: %d", GetLastError());        AfxMessageBox(szError);        return 1;     }    if(!aSocket.Listen(10))    {           char szError[256] = {0};        sprintf(szError, "Listen Faild: %d", GetLastError());        AfxMessageBox(szError);        return 1;    }    CString strText;    strText = "Server Start! \r\n";    aDlg->m_list_info.AddString(strText);    while(!m_exit)    {        if(!aSocket.Accept(serverSocket))        {            continue;        }        else        {            WIN32_FIND_DATA FileInfo;            serverSocket.Receive(&FileInfo,sizeof(WIN32_FIND_DATA));            CString strpath("");            CString strname("");            strname.Format("%s",FileInfo.cFileName);            strpath="C://";            CFile file;            if(!file.Open(strpath+strname,CFile::modeCreate|CFile::modeWrite))            {                AfxMessageBox("文件打开失败!已存在");                break;            }            //Receive文件的数据            UINT nSize = 0;            UINT nData = 0;            char szBuff[2048];            while(nSize<FileInfo.nFileSizeLow)            {                memset(szBuff,0x00,2048);                nData=serverSocket.Receive(szBuff,2048);                file.Write(szBuff,nData);                nSize+=nData;            }            serverSocket.Close();            file.Close();            SYSTEMTIME t; //系统时间结构             GetLocalTime(&t);            CString strinfo;            strinfo.Format("文件接收成功..保存在C盘下.\r\n时间:%d年%d月%d日 %2d:%2d:%2d \r\n",t.wYear,t.wMonth,t.wDay,                t.wHour,t.wMinute,t.wSecond);            aDlg->m_list_info.AddString(strinfo);        }    }    aSocket.Close();    serverSocket.Close();    aDlg->m_list_info.AddString("have closed");    return 0;}

步骤:一、创建CSocket 对象
   二、AfxSocketInit();//在哪个线程就在哪个线程里调用这个
   三、调用Socket()方法,来创建socket句柄
   四、调用SetSockOpt方法,配置socket
   五、Bind绑定一个端口
   六、Listen监听Socket
   七、循环调用Accept来判断有无接入的客户端
   八、读取数据,以客户端发送的方式再读取即可!

总体来说各框架的socket基本如出一辙。下面放出的DEMO,基于VC6.0的。
SendAll 与RecvAll
下载链接:http://download.csdn.net/detail/what951006/9885473 //使用的是WINAPI不是CSocket
更多文章:http://blog.csdn.net/what951006?viewmode=list
powered by:小乌龟在大乌龟背上~

0 0
原创粉丝点击