📄 chatdlg.cpp
字号:
strTemp+=m_ownHost+":\r\n"+str+"\r\n\r\n";
SetDlgItemText(IDC_EDIT_PUB_RECV,strTemp);*/
pubChatSock.sin_family=AF_INET;
pubChatSock.sin_addr.s_addr=INADDR_BROADCAST; //目的地址为广播地址
pubChatSock.sin_port=htons(55174); //群聊端口
//设定数据发送缓冲
len=str.GetLength();
wsabuf.buf=str.GetBuffer(len);
wsabuf.len=len+1;
//sendto(m_bSocket,smsg,256,0,(sockaddr*)&broadSock,sizeof(SOCKADDR));
WSASendTo(m_pubSocket,&wsabuf,1,&dwSend,0,(SOCKADDR*)&pubChatSock,sizeof(SOCKADDR),NULL,NULL);
//发送群聊信息
SetDlgItemText(IDC_EDIT_PUB_SEND,""); //清空发送编辑框中文本
}
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////以下为私聊的函数(有一部分私聊函数在CPriChatDlg类中定义)/////////////////////
//用户双击主对话框用户列表中某用户的响应函数
void CChatDlg::OnDblclkListUser()
{
// TODO: Add your control notification handler code here
int i=((CListBox*)GetDlgItem(IDC_LIST_USER))->GetCurSel();//获取用户双击列表框中第几个在线用户
/*CString str;
str.Format("%d",i);
MessageBox(str);*/
CChatUser * ptrUser=((CChatUser*)m_userArray.GetAt(i));//将被选中的用户信息从用户序列中取出
if(NULL==ptrUser->m_pChatDlg) //如果与被选中用户私聊的对话框还未创建
{
//创建私聊对话框
ptrUser->m_pChatDlg=new CPriChatDlg(ptrUser->m_host_IP,ptrUser->m_host_name,this);
ptrUser->m_pChatDlg->Create(IDD_PRICHAR_DIALOG);
if(m_ownIP==ptrUser->m_host_IP) //如果用户双击的是自己
ptrUser->m_pChatDlg->SetWindowText("与自己聊天"); //设定对话框标题
else //如果用户双击的是其他用户
ptrUser->m_pChatDlg->SetWindowText("与"+ptrUser->m_host_name+"聊天");//设定对话框标题
}
ptrUser->m_pChatDlg->ShowWindow(SW_SHOW); //显示窗口
ptrUser->m_pChatDlg->UpdateWindow(); //更新窗口
}
//收到私聊信息的消息响应函数
void CChatDlg::OnPRISock(WPARAM wParam,LPARAM lParam)
{
switch(LOWORD(lParam))
{
case FD_READ: //如果为网络读取事件
//MessageBox("OnPRISock");
SOCKADDR_IN priChatSock; //定义地址结构体
WSABUF wsabuf; //定义数据发送缓冲
wsabuf.buf=new char[200];
wsabuf.len=200;
DWORD dwRead; //实际接收字节数
DWORD dwFlag=0;
int len=sizeof(SOCKADDR);
WSARecvFrom(m_priSocket,&wsabuf,1,&dwRead,&dwFlag,(SOCKADDR*)&priChatSock,&len,NULL,NULL);
//接收私聊信息
int i,size=m_userArray.GetSize();
for(i=0;i<size;i++)
{//查找与发送信息的用户IP相同的,用户列表中的用户数据
if(priChatSock.sin_addr.S_un.S_addr==((CChatUser*)m_userArray.GetAt(i))->m_addr.sin_addr.S_un.S_addr)
break;
}
//MessageBox("recv");
CChatUser * ptrUser=((CChatUser*)m_userArray.GetAt(i));
//定义指向保存该用户信息的CChatUser类实例的指针
if(NULL==ptrUser->m_pChatDlg) //如果与该用户私聊的对话框未创建
{
//创建对话框
ptrUser->m_pChatDlg=new CPriChatDlg(ptrUser->m_host_IP,ptrUser->m_host_name,this);
ptrUser->m_pChatDlg->Create(IDD_PRICHAR_DIALOG);
ptrUser->m_pChatDlg->SetWindowText("与"+ptrUser->m_host_name+"聊天");
}
ptrUser->m_pChatDlg->ShowWindow(SW_SHOW); //显示窗口
ptrUser->m_pChatDlg->UpdateWindow(); //更新窗口
//GetDlgItem(IDC_EDIT_SENT,(HWND*)ptrUser->m_pChatDlg)->SetWindowText(wsabuf.buf,sizeof(wsabuf.buf)+1);
CString str;
//调用CPriChatDlg成员函数SetRecvText,将发送信息者的主机名和其发送的信息
//显示在私聊对话框的接收信息编辑框中
str=ptrUser->m_host_name+":\r\n";
ptrUser->m_pChatDlg->SetRecvText(&str);
str.Format("%s\r\n\r\n",wsabuf.buf);
ptrUser->m_pChatDlg->SetRecvText(&str);
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////以下为文件传输函数(有一部分文件传输函数定义在CPriChatDlg类中)/////////////////
//收到文件传输控制信息的消息响应函数
void CChatDlg::OnFileConnSock(WPARAM wParam,LPARAM lParam)
{
switch(LOWORD(lParam))
{
case FD_READ: //如果为网络读取事件
//MessageBox("OnFileConnSock");
SOCKADDR_IN fileCtrlRecvSock; //定义地址结构体
WSABUF wsabuf; //定义数据发送缓冲
wsabuf.buf=new char[50];
wsabuf.len=50;
DWORD dwRead; //实际接收字节数
DWORD dwFlag=0;
int len=sizeof(SOCKADDR);
WSARecvFrom(m_fileSocket,&wsabuf,1,&dwRead,&dwFlag,(SOCKADDR*)&fileCtrlRecvSock,&len,NULL,NULL);
//接收文件传输控制信息
int i,size=m_userArray.GetSize();
for(i=0;i<size;i++)
{//查找与发送信息的用户IP相同的,用户列表中的用户数据
if(fileCtrlRecvSock.sin_addr.S_un.S_addr==((CChatUser*)m_userArray.GetAt(i))->m_addr.sin_addr.S_un.S_addr)
break;
}
CChatUser * ptrUser=((CChatUser*)m_userArray.GetAt(i));
//定义指向保存该用户信息的CChatUser类实例的指针
if(NULL==ptrUser->m_pChatDlg) //如果与该用户私聊的对话框未创建
{
//创建对话框
ptrUser->m_pChatDlg=new CPriChatDlg(ptrUser->m_host_IP,ptrUser->m_host_name,this);
ptrUser->m_pChatDlg->Create(IDD_PRICHAR_DIALOG);
ptrUser->m_pChatDlg->SetWindowText("与"+ptrUser->m_host_name+"聊天");
}
ptrUser->m_pChatDlg->ShowWindow(SW_SHOW); //显示窗口
ptrUser->m_pChatDlg->UpdateWindow(); //更新窗口
CString str=wsabuf.buf; //保存接收数据
if("go"==str) //如果收到数据“go”,即接收方同意接收文件
{
AfxBeginThread(FileSendProc,ptrUser); //启动文件发送线程
/*注释部分为单线程模式
ptrUser->m_pChatDlg->FileButtonCtrl(0x00);
CString strTemp;
strTemp="文件传送中,请稍候。\r\n\r\n";
ptrUser->m_pChatDlg->SetRecvText(&strTemp);
CSocket sockSrvr;
sockSrvr.Create(800);
sockSrvr.Listen();
CSocket sockRecv;
sockSrvr.Accept(sockRecv);
SOCKET_STREAM_FILE_INFO StreamFileInfo;
WIN32_FIND_DATA FindFileData;
FindClose(FindFirstFile(ptrUser->m_pChatDlg->m_pathName,&FindFileData));
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,ptrUser->m_pChatDlg->m_myFile.GetFileTitle());
StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
sockRecv.Send(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));
UINT dwRead=0;
while(dwRead<StreamFileInfo.nFileSizeLow)
{
byte* data = new byte[1024];
UINT dw=ptrUser->m_pChatDlg->m_myFile.Read(data, 1024);
sockRecv.Send(data, dw);
dwRead+=dw;
}
ptrUser->m_pChatDlg->m_myFile.Close();
sockRecv.Close();
strTemp="文件发送完毕!\r\n\r\n";
ptrUser->m_pChatDlg->SetRecvText(&strTemp);
AfxMessageBox("发送完毕!");
ptrUser->m_pChatDlg->FileButtonCtrl(0x90);*/
}
else if("stop"==str) //如果收到数据“stop”,即接收方拒绝接收文件
{
str=ptrUser->m_host_name+"拒绝接收该文件!\r\n\r\n";
ptrUser->m_pChatDlg->SetRecvText(&str); //显示对方拒绝接收文件
ptrUser->m_pChatDlg->FileButtonCtrl(0x90);
//Enable“传输文件”和“退出”按钮,Disable“接收文件”和“拒绝接收”按钮
}
else //如果收到其他信息,即为其他用户向你发送的文件的文件名
{
//MessageBox("recv");
//GetDlgItem(IDC_EDIT_SENT,(HWND*)ptrUser->m_pChatDlg)->SetWindowText(wsabuf.buf,sizeof(wsabuf.buf)+1);
//CString str;
//str=ptrUser->m_host_name+":\r\n";
//ptrUser->m_pChatDlg->SetRecvText(&str);
str=ptrUser->m_host_name+"向你发送此文件:"+wsabuf.buf+"\r\n请按'接收文件'按钮或'拒绝接收'按钮\r\n\r\n";
//显示某用户向你发送文件
//str="haha\r\n";
//str.Format("%s\r\n\r\n",wsabuf.buf);
ptrUser->m_pChatDlg->m_fileTitle=wsabuf.buf;//保存文件名
ptrUser->m_pChatDlg->SetRecvText(&str); //显示文件名
ptrUser->m_pChatDlg->FileButtonCtrl(0x60);
//Disable“传输文件”和“退出”按钮,Enable“接收文件”和“拒绝接收”按钮
}
break;
}
}
//文件发送线程函数
UINT FileSendProc(LPVOID lParam)
{
//MessageBox("WorkThreadProc");
CChatUser *ptrUser = (CChatUser *)lParam;
//取出收到的信息(指向保存接收方信息的CChatUser实例的指针)
ptrUser->m_pChatDlg->FileButtonCtrl(0x00);
//Disable“传输文件”、“接收文件”、“拒绝接收”和“退出”按钮
CString strTemp;
strTemp="文件发送中,请稍候。\r\n\r\n";
ptrUser->m_pChatDlg->SetRecvText(&strTemp);
CSocket sockSrvr; //建立异步套接字
sockSrvr.Create(55180); //端口为55180
sockSrvr.Listen(); //开始监听
CSocket sockRecv; //建立异步套接字
sockSrvr.Accept(sockRecv); //接收请求
SOCKET_STREAM_FILE_INFO StreamFileInfo; //定义描述文件信息结构体
WIN32_FIND_DATA FindFileData;
//复制文件信息
FindClose(FindFirstFile(ptrUser->m_pChatDlg->m_pathName,&FindFileData));
memset(&StreamFileInfo,0,sizeof(SOCKET_STREAM_FILE_INFO));
strcpy(StreamFileInfo.szFileTitle,ptrUser->m_pChatDlg->m_myFile.GetFileTitle());
StreamFileInfo.dwFileAttributes = FindFileData.dwFileAttributes;
StreamFileInfo.ftCreationTime = FindFileData.ftCreationTime;
StreamFileInfo.ftLastAccessTime = FindFileData.ftLastAccessTime;
StreamFileInfo.ftLastWriteTime = FindFileData.ftLastWriteTime;
StreamFileInfo.nFileSizeHigh = FindFileData.nFileSizeHigh;
StreamFileInfo.nFileSizeLow = FindFileData.nFileSizeLow;
sockRecv.Send(&StreamFileInfo,sizeof(SOCKET_STREAM_FILE_INFO));//发送文件信息
DWORD dwReadlo=0; //已发送大小的低双字
DWORD dwReadhi=0; //已发送大小的高双字
short present=0; //已发送百分比
unsigned __int64 temp1=(StreamFileInfo.nFileSizeHigh*2^32+StreamFileInfo.nFileSizeLow)/100;
//文件大小的1/100
unsigned __int64 temp2;
//发送文件
while(dwReadhi<=StreamFileInfo.nFileSizeHigh)
{
while(dwReadlo<StreamFileInfo.nFileSizeLow)
{
byte* data = new byte[1024];
UINT dw=ptrUser->m_pChatDlg->m_myFile.Read(data, 1024); //读取1KB
sockRecv.Send(data, dw); //发送
free(data); //释放内存
dwReadlo+=dw;
//更新文件发送进度
if(0==StreamFileInfo.nFileSizeHigh) //如果文件小于4GB
{
if(dwReadlo>=present*temp1) //如果多传了1%
{
strTemp.Format("%d",present);
ptrUser->m_pChatDlg->SetProgress(&strTemp,TRUE);//更新进度
present++;
}
}
else //如果文件大于4GB
{
temp2=dwReadhi*2^32+dwReadlo; //已发送文件大小
if(temp2>=present*temp1) //如果多传了1%
{
strTemp.Format("%d",present);
ptrUser->m_pChatDlg->SetProgress(&strTemp,TRUE);//更新进度
present++;
}
}
}
dwReadlo=0;
dwReadhi++;
}
strTemp.Format("%d",100); //发送完毕,将进度置为100%
ptrUser->m_pChatDlg->SetProgress(&strTemp,TRUE);//更新进度
ptrUser->m_pChatDlg->m_myFile.Close(); //关闭文件
sockRecv.Close(); //关闭套接字
//显示提示信息
strTemp="文件发送完毕!\r\n\r\n";
ptrUser->m_pChatDlg->SetRecvText(&strTemp);
//AfxMessageBox("发送完毕!");
ptrUser->m_pChatDlg->FileButtonCtrl(0x90);
//Enable“传输文件”和“退出”按钮,Disable“接收文件”和“拒绝接收”按钮
ptrUser->m_pChatDlg->SetProgress(&strTemp,FALSE); //清除文件进度显示
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -