• TCP发送文件(转)


    //文件传送线程//服务器发送文件,客户端发送文件消息
    UINT threadSendFile(LPVOID pvar)
    {
        CDlgSendMessage *pDlg = (CDlgSendMessage *) pvar;
    
    CFile m_fSendfile;
    m_fSendfile.Close();
    
    if (!m_fSendfile.Open(pDlg->m_sendfilepath, CFile::modeRead | CFile::typeBinary))
    {
       AfxMessageBox("打开文件失败!");
       return false;
    }
    
    
    SOCKET sSendMsg;//客户端套接字
    SOCKADDR_IN inetAddr;
    sSendMsg = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    
    if (INVALID_SOCKET == sSendMsg)
    {
       AfxMessageBox( "创建客户端发送套接字失败!");
       m_fSendfile.Close();
       return 0;
    }
    
    inetAddr.sin_family = AF_INET;
    inetAddr.sin_port = htons(PUB_MSG_PORT);
    inetAddr.sin_addr.s_addr= inet_addr(pDlg->m_receiveip);//为接受文件者IP
    
    
    
      
    if (SOCKET_ERROR == connect(sSendMsg, (SOCKADDR *)&inetAddr, sizeof(SOCKADDR_IN)))//为接受文件者
    {
    
             
         AfxMessageBox("对方不在线,不存在监听套接字失败!");
       closesocket(sSendMsg);
       m_fSendfile.Close();
       return 0;
    }
    
    char buff[MAX_BUF_SIZE] = "";
    CString strMsgSend("1001/");
    CString strSize;
    
    //计算文件大小
    if (pDlg->m_fiSendFile.nFileSizeLow / (1024 * 1024) != 0)
    {
       strSize.Format("%.2fMB", pDlg->m_fiSendFile.nFileSizeLow / (1024.0 * 1024));
    }
    else
    {
       strSize.Format("%.2fKB", pDlg->m_fiSendFile.nFileSizeLow / (1024.0));
    }
    
    memcpy(buff, pDlg->m_fiSendFile.szFileTitle, sizeof(pDlg->m_fiSendFile.szFileTitle));
    strMsgSend += buff;
    strMsgSend += "/";
    strMsgSend += strSize;
    strMsgSend += "/";
    //发送文件标题,文件大小//作为客户端发消息和接受套接字
    
    
    if (SOCKET_ERROR == send(sSendMsg, strMsgSend.GetBuffer(0), strMsgSend.GetLength(), 0))
    {
       AfxMessageBox( "发送消息失败!: threadSendFile");
       closesocket(sSendMsg);
       m_fSendfile.Close();
       return 0;
    }
    
    memset(buff, 0, MAX_BUF_SIZE);
    
    
    if (SOCKET_ERROR == recv(sSendMsg, buff, MAX_BUF_SIZE, 0))//收到对方反馈信息//收到同意接受信息
    {
       AfxMessageBox( "接收消息失败!: threadSendFile");
       closesocket(sSendMsg);
       m_fSendfile.Close(); 
       return 0;
    }
    
    
    //解析对方的确认信息
    CString strCmd;
    strCmd += buff;
    strCmd = strCmd.Left(4);
    int iCmd = -1;
    iCmd = atoi(strCmd);
    if (MSG_ACCEPT != iCmd)
    {
       AfxMessageBox( "对方拒绝接收文件!: threadSendFile");
       closesocket(sSendMsg);
       m_fSendfile.Close();
    
       return false;//
    }
    
    //对方同意接收文件,开始发送
    
    
    //创建服务器 发送文件socket, 打开FILE_PORT
    SOCKET sSendFile;//监听套接字
    SOCKET sAccept;//发送接受套接字
    SOCKADDR_IN inetAddrSendFile;
    SOCKADDR_IN inetAddrAccept;
    
    sSendFile = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if (INVALID_SOCKET == sSendFile)
    {
       AfxMessageBox( "创建套接字错误!: threadSendFile");
       closesocket(sSendMsg);
         m_fSendfile.Close();
       return 0;
    }
    
    inetAddrSendFile.sin_addr.s_addr = htonl(INADDR_ANY);
    inetAddrSendFile.sin_port    = htons(PUB_FILE_PORT);
    inetAddrSendFile.sin_family    = AF_INET;
    
    if (SOCKET_ERROR == bind(sSendFile, (SOCKADDR *)&inetAddrSendFile, sizeof(SOCKADDR)))
    {
       AfxMessageBox( "绑定套接字错误!: threadSendFile");
       closesocket(sSendMsg);
       closesocket(sSendFile);
       m_fSendfile.Close();
       return 0;
    }
    
    if (SOCKET_ERROR == listen(sSendFile, 5))
    {
       AfxMessageBox( "监听错误!: threadSendFile");
       closesocket(sSendMsg);
       closesocket(sSendFile);
       m_fSendfile.Close();
       return 0;
    }
    
    int iLen = sizeof(SOCKADDR);
    sAccept = accept(sSendFile, (SOCKADDR *)&inetAddrAccept, &iLen);
    
    if (INVALID_SOCKET == sAccept)
    {
       AfxMessageBox( "accept socket error occurred!: threadSendFile");
       closesocket(sSendMsg);
       closesocket(sSendFile);
       m_fSendfile.Close();
       return 0;
    }
    
    //发送文件信息给对方
    char buffInfo[MAX_BUF_SIZE] = "";
    memcpy(buffInfo, &pDlg->m_fiSendFile, sizeof(pDlg->m_fiSendFile));
    send(sAccept, buffInfo, sizeof(pDlg->m_fiSendFile), 0);
    memset(buffInfo, 0, MAX_BUF_SIZE);
    
    //对方同意接收huozebujieshou,开始传送
       
        recv(sAccept, buffInfo, MAX_BUF_SIZE, 0);//对方不保持就不往下走
    
    //循环发送文件
    DWORD dwRead = 0;
    DWORD dwCurrentRead = 0;
    BYTE *bReadBuff = new BYTE[MAX_BUF_SIZE];
    
    //设置发送进度
    
    
    while (dwRead < pDlg->m_fiSendFile.nFileSizeLow)
    { 
       dwCurrentRead = 0;
       memset(bReadBuff, 0, MAX_BUF_SIZE);
       dwCurrentRead = m_fSendfile.Read(bReadBuff, MAX_BUF_SIZE);//读数据到缓冲区
       if (SOCKET_ERROR == send(sAccept, (char *)bReadBuff, dwCurrentRead, 0))//发送数据
       {
        AfxMessageBox( "文件发送中断!: threadSendFile");//如果对方取消持,发送方也也一直往下走
        closesocket(sSendMsg);
        closesocket(sSendFile);
        m_fSendfile.Close();
        break;
       }
    
       dwRead += dwCurrentRead;//已经发送数据
        CString   str;   
            str.Format("%d",   dwRead);
       AfxMessageBox("已经发送"+str);
    
    }
    AfxMessageBox("发送完成");
    delete bReadBuff; //释放堆内存
    //结束时处理
    m_fSendfile.Close();//文件关闭
    if (INVALID_SOCKET != sAccept)
    {
       closesocket(sAccept);//关闭接受套接字
    }
    if (INVALID_SOCKET != sSendFile)
    {
       closesocket(sSendFile);//关闭发送套接字
    }
    
    
    AfxEndThread(0);
    
    return 1;
    }
    
    //客户端文件接收线程
    UINT threadRecvFile(LPVOID pvar)
    {
    
        char * m_sip=(char *)pvar;
    SOCKET sFileRecv;
    SOCKADDR_IN inetAddr;
    
    //新建一个客户socket,连接文件 发送方服务器 接收文件
    sFileRecv = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if (INVALID_SOCKET == sFileRecv)
    {
       AfxMessageBox( "创建套接字失败 : threadRecvFile");
       AfxEndThread(0);
       return 0;
    }
    
    inetAddr.sin_family    = AF_INET;
    inetAddr.sin_port    = htons(PUB_FILE_PORT);
    inetAddr.sin_addr.s_addr = inet_addr(m_sip);
    
    
    if (SOCKET_ERROR == connect(sFileRecv, (SOCKADDR *)&inetAddr, sizeof(SOCKADDR)))//连接服务器IP
    {
       AfxMessageBox("连接对方主机错误 : threadRecvFile");
       closesocket(sFileRecv);
       AfxEndThread(0);
       return 0;
    }
    
    //接收文件信息
    FileInfo fiRecvFile;
    
    if (SOCKET_ERROR == recv(sFileRecv, (char *)&fiRecvFile, sizeof(FileInfo), 0))
    {
       AfxMessageBox("接收文件信息错误 : threadRecvFile");
       closesocket(sFileRecv);
       AfxEndThread(0);
       return 0;
    }
    
    CString strFileInfo;
    double nfileSize = 0.0;
    if (fiRecvFile.nFileSizeLow / (1024 * 1024) != 0)
    {
       nfileSize = fiRecvFile.nFileSizeLow / (1024 * 1024);
       strFileInfo.Format("正在接收文件...\n 来自[%s], \n文件名[%s] 大小:[%.2f]MB", 
            inet_ntoa(inetAddr.sin_addr), fiRecvFile.szFileTitle, nfileSize);
    }
    else
    {
       nfileSize = fiRecvFile.nFileSizeLow / (1024);
       strFileInfo.Format("正在接收文件...\n 来自[%s], \n文件名[%s] 大小:[%.2f]KB", 
            inet_ntoa(inetAddr.sin_addr), fiRecvFile.szFileTitle, nfileSize);
    }
    
    
    
    CFileDialog fdlgSave( FALSE,NULL,fiRecvFile.szFileTitle,
           OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
           _T("所有 (*.*)|*.*|"));
    
    char buff[MAX_BUF_SIZE] = "";
    CAcModuleResourceOverride thisResource;
    if (fdlgSave.DoModal() != IDOK)
    {
      
       sprintf(buff, "%d", MSG_REJECT);
       send(sFileRecv, buff, sizeof(buff), 0);
        closesocket(sFileRecv);//导致发送文件中端
        AfxEndThread(0);
    }
    
    CString strFilePath;
    strFilePath = fdlgSave.GetPathName();
    
    CFile fRecvedFile(strFilePath, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
    
    DWORD dwTotalRead;
    DWORD dwCurrentRead;
    
    dwTotalRead   = 0; //接收总字节
    dwCurrentRead = 0; //此次接收字节
    BYTE *dataBuff = new BYTE[MAX_BUF_SIZE]; //分配堆内存缓冲
    
    //开始接收
    memset(buff, 0, sizeof(buff));
    sprintf(buff, "%d", MSG_BEGIN);
    send(sFileRecv, buff, sizeof(buff), 0);
    
    
    while (dwTotalRead < fiRecvFile.nFileSizeLow)
    {
       dwCurrentRead = 0;
       memset(dataBuff, 0, MAX_BUF_SIZE);
    
       dwCurrentRead = recv(sFileRecv, (char *)dataBuff, MAX_BUF_SIZE, 0);
       if (0 == dwCurrentRead || SOCKET_ERROR == dwCurrentRead)
       {
        CString strFileRecvInfo;
        strFileRecvInfo.Format("接收:%s失败!", fiRecvFile.szFileTitle);
      
        break;
       }
       fRecvedFile.Write(dataBuff, dwCurrentRead);
       dwTotalRead += dwCurrentRead;
    //   CString str;
    //   str.Format("%d",dwTotalRead);
    //   AfxMessageBox("已经接受"+str);
    
       double iCompleted = 0.0;
       iCompleted = (dwTotalRead * 1.0) / fiRecvFile.nFileSizeLow;
       iCompleted *= 10.0;
       CString strSavedInfo;
       strSavedInfo.Format("%d", iCompleted);
    
    }
    
    delete dataBuff; //释放堆内存
    
    CString strFileRecvInfo;
    strFileRecvInfo.Format("接收:%s完成!", fiRecvFile.szFileTitle);
    AfxMessageBox(strFileRecvInfo);
    
    if (sFileRecv != INVALID_SOCKET)
    {
       closesocket(sFileRecv);
    }
    
    //关闭文件
    fRecvedFile.Close();
    //清空文件信息
    // memset(&pDlg->m_fiSendFile, 0, sizeof(pDlg->m_fiSendFile));
    //
    AfxEndThread(0);
    return 1;
    }  
    
    //服务监听线程//建立服务器模型
    UINT threadServer(LPVOID pvar) 
    {
    
    SOCKADDR_IN inetAddr;
    SOCKADDR_IN inetAccept;
    SOCKET sAccept;
    SOCKET MySock;
        //服务器监听套接字MYSOCK;
    
    
    MySock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if (INVALID_SOCKET == MySock)
    {
       AfxMessageBox( "套接字创建失败!");
       return FALSE;
    }
    
    inetAddr.sin_family = AF_INET;
    inetAddr.sin_port = htons(PUB_MSG_PORT);   //消息监听端口
    //inetAddr.sin_port = 0;
    inetAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    
    //绑定
    if (INVALID_SOCKET == bind(MySock, (SOCKADDR *)&inetAddr, sizeof(SOCKADDR)))
    {
       AfxMessageBox( "套接字绑定错误 : threadServer!");
       closesocket(MySock);
       return 0;
    }
    
    //监听
    if (0 != listen(MySock, 5))
    {
       AfxMessageBox("套接字监听错误 : threadServer!");
       return 0;
    }
    
    //    AfxMessageBox("消息服务启动成功");
    
    //accept
    int ilen = sizeof(SOCKADDR_IN);
    
    while(TRUE)
    {//服务器会话套接字
    
       sAccept = accept(MySock, (SOCKADDR *)&inetAccept, &ilen);
    
       if (INVALID_SOCKET == sAccept)
       {
         AfxMessageBox("接受套接字失败 : threadServer!");
        return 0;
       }
      
       //启动消息处理线程处理新到达的消息
      
       //分配堆内存,存放客户socket信息
       SocketInfo *psInfo = new SocketInfo;
       memset(psInfo, 0, sizeof(SocketInfo));
       psInfo->sNow   = sAccept;
       psInfo->inetAddr = inetAccept;//客户机的地址
      
        AfxBeginThread(threadRecvMsg, (LPVOID)psInfo);
    }//while
    
    return 1;
    }
    
    //服务器处理 消息处理线程,新消息到达后启动,处理完毕关闭
    UINT threadRecvMsg(LPVOID pvar)
    {
    SocketInfo *psockInfo = (SocketInfo *)pvar;
    SocketInfo sockInfo = *psockInfo;
    delete psockInfo; //释放堆内存
    //每个线程里都有单独的内存,必须释放才能引用,实际上是子线程偷了父线程的内存
      
    
    int iRecv = -1;
    char buff[MAX_BUF_SIZE] = "";
    char szMsg[256] = "";
    
    //开始接收消息
    iRecv = recv(sockInfo.sNow, buff, sizeof(buff), 0);//
    if (SOCKET_ERROR == iRecv)
    {
       closesocket(sockInfo.sNow);
       AfxMessageBox( "接收消息出错!: threadRecvMsg");
       AfxEndThread(0);
    }
    
    //1001/暴风影音2007.exe/32MB/
    strcpy(szMsg, buff);
    int itype = 0;
    CString strTemp;
    CString strInMsg;
    strTemp += szMsg;
    strInMsg += szMsg;
    strTemp = strTemp.Left(4);
    itype = atoi(strTemp);
    
    //判断是否为文件到达消息
    if (MSG_NEW_FILE == itype)
    {
    
       CString strMsgInfo;
       CString strHost;
       CString strFileName;
       CString strSize;
      
       int i, j;
       i = 0;
       j = 0;
       i = strInMsg.Find("/");
       j = strInMsg.Find("/", i + 1);
      
       //取得文件名称
       strFileName = strInMsg.Mid(i + 1, j - i - 1);
       strInMsg.TrimRight("/");
       //取得文件大小
       strSize = strInMsg.Right(strInMsg.GetLength() - strInMsg.ReverseFind('/') - 1);
      
       strMsgInfo.Format("[文件来源:%s]\n[文件名称:%s]\n[文件大小:%s]", inet_ntoa(sockInfo.inetAddr.sin_addr), strFileName, strSize);
       strMsgInfo += "\n同意接收吗?";
       CAcModuleResourceOverride thisResource;
       if (IDYES == MessageBox(NULL, strMsgInfo, "新消息", MB_YESNO))
       {
        char buffSend[MAX_BUF_SIZE] = "";
        char sztemp[20] = "";
        itoa(MSG_ACCEPT, sztemp, 10); 
        strcpy(buffSend, sztemp);
       
        //发送同意接收消息给对方
        if (SOCKET_ERROR == send(sockInfo.sNow, buffSend, sizeof(buffSend), 0))
        {
           AfxMessageBox( "发送消息失败 : threadRecvMsg");
         closesocket(sockInfo.sNow);
         AfxEndThread(0);
        }//if
       
      
        char * senderip;
        senderip=inet_ntoa(sockInfo.inetAddr.sin_addr);
        //启动文件接收线程   
        AfxBeginThread(threadRecvFile, (LPVOID)senderip);
      
       
       }//if
       else
       {
        char buffSend[MAX_BUF_SIZE] = "";
        char sztemp[20] = "";
        itoa(MSG_REJECT, sztemp, 10); 
        strcpy(buffSend, sztemp);
       
        //发送拒绝接收消息给对方
        if (SOCKET_ERROR == send(sockInfo.sNow, buffSend, sizeof(buffSend), 0))
        {
         AfxMessageBox( "发送消息失败 : threadRecvMsg");
         closesocket(sockInfo.sNow);
         AfxEndThread(0);
        }//if
       }//else
      
    }//if
    else
    {
       AfxMessageBox("无法识别的消息");
    }//else
    
    
    return 0;
    }
    

  • 相关阅读:
    2020年9月29日
    随机生成验证码
    动手动脑java语法基础
    Java语法之动手实验
    代码大全2 读书笔记
    java动手动动脑之字串联接
    二柱子问题
    生成随机四则运算1
    可变参数
    2020年9月30日
  • 原文地址:https://www.cnblogs.com/lebronjames/p/1793342.html
Copyright © 2020-2023  润新知