当前位置:首页 > 潘睿哲 基于UDP协议的聊天工具的设计(最终版)
第六章 关键源程序
AfxSocketInit()是一个BOOL型函数,作用是初始化套接字,成功返回非
0,不成功返回0。
if(!AfxSocketInit()) //判断这个函数是否为0 {
AfxMessageBox(\加载套接字库失败!\); //为0会有提示 return FALSE;
//返回FALSE,关闭
} else {
AfxMessageBox(\加载套接字库成功!\); }
InitSocket()函数用来初始化套接字,并和本地信息进行绑定。
BOOL CChatDlg::InitSocket() {
m_socket=socket(AF_INET,SOCK_DGRAM,0); /*用变量m_socket接
收创建的套接字。Socket()是1个创建套接字的函数,如果创建不成功,返回INVALID_SOCKET。*/
if(m_socket==INVALID_SOCKET) /*如果创建套接字失败,则返回
FALSE。*/
{
MessageBox(\创建套接字失败!\);
return FALSE; }
SOCKADDR_IN addrSock; /*定义SOCKADDR_IN类型结构体
addrSock*/
8
//给结构体里的各个变量进行赋值。
addrSock.sin_family=AF_INET; //用网际域
addrSock.sin_port=htons(5000); /*端口为5000,用htons函数转换成网
络字节序*/
//获取主机IP地址,并赋值给结构体内变量。
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //用bind函数将本地地址和建立的套接字进行绑定。
int retval;
retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)); //进行判断,如果绑定失败,关闭套接字,进行消息提示,返回FALSE。 if(SOCKET_ERROR==retval) {
closesocket(m_socket);
MessageBox(\套接字与本地机地址绑定失败!\);
return FALSE; } else {
MessageBox(\套接字与本地机地址绑定成功!\);
}
return TRUE; }
建立1个结构体RECVPARAM,并用指针pRecvParam指向它。
RECVPARAM *pRecvParam=new RECVPARAM; 配1个动态空间*/
/*用new给指针分
pRecvParam->hwnd=m_hWnd; //给结构体变量赋初值,传递对话框句柄 pRecvParam->sock=m_socket; //传递套接字
9
用CreateThread创建一个新的线程,然后创建线程句柄hThread,用来接收CreateThread返回的句柄值。
HANDLE
hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread); /*关闭新线程的句柄,递减线程内核对象的使用
计数。*/
新线程执行函数RecvProc()
DWORD WINAPI CChatDlg::RecvProc(LPVOID lpParameter) {
//取出所传递的2个参数值,1个是套接字,1个是对话框句柄。 SOCKET sock=((RECVPARAM*)lpParameter)->sock; HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
SOCKADDR_IN addrFrom;/*定义1个套接字地址结构变量,接收发送端
的地址信息。*/
int len=sizeof(SOCKADDR); //接收返回地址结构体的长度。 char recvBuf[100]; //字符数组,用来接收到来的数据。 char tempBuf[100]; int retval;
while(TRUE) //做一个循环,让它不断接收数据 {
retval=recvfrom(sock,recvBuf,100,0, //retval接收recvfrom的返回值
(SOCKADDR*)&addrFrom,&len);
//用来存放格式化后的数据。
if(retval==SOCKET_ERROR) /*如果返回SOCKET_ERROR,调用
break语句,终止循环。*/
{
10
break; }
//如果无错误,格式化recvBuf,将格式化后的数据放入tempBuf中。
sprintf(tempBuf,\说:%s\,inet_ntoa(addrFrom.sin_addr),
recvBuf); /*调用inet_ntoa,将发送端IP地址转换为点分十进制
字符串*/
//将接收到的数据传递给对话框。
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf); }
return 0; }
对接收到的消息进行处理,使得能够按照一定格式输出。对于接收数据框来说,接收到的最新数据应该放到最顶端,以前的数据应该依次往下排列。
void CChatDlg::OnRecvData(WPARAM wParam,LPARAM lParam) { }
发送函数
void CChatDlg::OnBtnSend()
11
CString str=(char*)lParam; //把lParam转换成字符型指针,然后赋给str。 CString strTemp; //接收旧的数据。
GetDlgItemText(IDC_EDIT_RECV,strTemp);//从控件中得到文本。 str+=\; //让新的数据加1个换行。。 str+=strTemp; //再下一行加入先前的数据。
SetDlgItemText(IDC_EDIT_RECV,str);//将数据放回接收的编辑框。
共分享92篇相关文档