VC6.0创建基于UDP协议的网络聊天程序
只有一个工程UDP,服务器和客户端都是这个工程,因为UDP中C/S区分不强化
2.为控件绑定变量和消息函数
启动按钮消息函数为Onstart()
发送按钮为OnSendInfo()
3.写一个线程函数用于接收消息(不是成员函数,注意!,在CUDPDlg.cpp文件中定义)如下:
UINT ThreadProcRecv(LPVOID pParam)
{
CUDPDlg * dlg=(CUDPDlg*)pParam; WORD wVertionRequested;
WSADATA wsadata;
int err;
wVertionRequested = MAKEWORD(2,2);
err=WSAStartup(wVertionRequested,&wsadata);
if(err!=0)
{
dlg->MessageBox(“加载版本2.2失败!”);
return 0;
}
if(LOBYTE(wsadata.wVersion)!=2||HIBYTE(wsadata.wHighVersion)!=2)
{
dlg->MessageBox(“加载版本不是套接字2.2版本!”);
WSACleanup();
return 0;
} SOCKET socketServer=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addr; addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addr.sin_family=AF_INET;
addr.sin_port=htons(dlg->m_recvport); bind(socketServer,(SOCKADDR *)&addr,sizeof(SOCKADDR)); SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
char buffer[100];
while(TRUE)
{
recvfrom(socketServer,buffer,100,0,(SOCKADDR *)&addrClient,&len); CString info;
info.Format(“%s%s”,”他说:”,buffer);
dlg->m_listbox.AddString(info);
dlg->SetHScroll();
dlg->GetDlgItem(IDC_LIST1)->PostMessage(WM_VSCROLL,SB_BOTTOM,0);
} closesocket(socketServer);
WSACleanup();
return 0;
}4.编写消息函数 void CUDPDlg::OnStart()
{
UpdateData(TRUE); GetDlgItem(IDC_EDIT4)->EnableWindow(FALSE);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE);
GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE);
if(AfxBeginThread(ThreadProcRecv,this))
MessageBox(“启动成功!”);
} void CUDPDlg::OnSendInfo()
{
GetDlgItem(IDC_EDIT3)->SetFocus(); UpdateData(TRUE);
if(m_sendinfo.IsEmpty())
{
MessageBox(“消息为空”);
return;
}
WORD wVertionRequested;
WSADATA wsadata;
int err;
wVertionRequested = MAKEWORD(2,2);
err=WSAStartup(wVertionRequested,&wsadata);
if(err!=0)
{
MessageBox(“加载套接字2.2版本失败!”);
return;
}
if(LOBYTE(wsadata.wVersion)!=2||HIBYTE(wsadata.wHighVersion)!=2)
{
MessageBox(“加载版本不是套接字2.2版本!”);
WSACleanup();
return;
} SOCKET socketServer=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addr; addr.sin_addr.S_un.S_addr=inet_addr(m_ip.GetBuffer(0));
addr.sin_family=AF_INET;
addr.sin_port=htons(m_sendport); char * send;
send=m_sendinfo.GetBuffer(m_sendinfo.GetLength()); CString text;
text.Format(“%s%s”,”我说:”,send);
m_listbox.AddString(text);
SetHScroll(); sendto(socketServer,send,m_sendinfo.GetLength()+1,0,(SOCKADDR *)&addr,sizeof(SOCKADDR)); closesocket(socketServer);
WSACleanup(); m_sendinfo=””;
UpdateData(FALSE);
GetDlgItem(IDC_LIST1)->PostMessage(WM_VSCROLL,SB_BOTTOM,0);}5.至此已基本完成,运行实例:1.打开一个客户端(端口号相同)2.打开一个客户端(端口号不同)
3.打开2个客户端(一台机子)
遗漏点补充:
1.为了方便,可以勾选发送按钮属性框中的默认按钮选项,可以通过enter发送消息
2.列表框控件无法设置水平滚动条,必须自己添加函数
添加函数前先把列表框属性水平滚动条勾选上然后添加下面成员函数
void CUDPDlg::SetHScroll()
{
CDC* dc = GetDC();
SIZE s;
int index;
CString str;
long temp;
for(index= 0; index< m_listbox.GetCount(); index++)
{
m_listbox.GetText(index,str);
s = dc->GetTextExtent(str,str.GetLength()+1); // 获取字符串的像素大小
// 如果新的字符串宽度大于先前的水平滚动条宽度,则重新设置滚动条宽度
// IDC_LISTBOX为m_List的资源ID
temp = (long)SendDlgItemMessage(IDC_LIST1, LB_GETHORIZONTALEXTENT, 0, 0); //temp得到滚动条的宽度
if (s.cx > temp)
{
SendDlgItemMessage(IDC_LIST1, LB_SETHORIZONTALEXTENT, (WPARAM)s.cx, 0);
}
}
ReleaseDC(dc);
}以后每当使用向列表框添加语句时,在后面调用该函数即可3.UpdateData(TRUE)和UpdateData(FALSE)非常重要,不可缺少,不懂请百度基本就这样了,希望对你们有所帮助!工程文件百度网盘下载:https://pan.baidu.com/s/1d1SlR3gJzZA4XEGJmquJLw 提取码:nu77