//文件传送线程//服务器发送文件,客户端发送文件消息
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;
}
//文件传送线程//服务器发送文件,客户端发送文件消息
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;
}