正文

第16课 2007-05-01 15:39:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/bclz/25443.html

分享到:

1.事件对象:来实现线程的同步。与互斥对象一样均属于内核对象。            当人工重置有信号时,所有线程均得到信号,所以不能设为人工重置。代码就不贴了。            通过创建匿名的事件对象,也可以让一个程序只能运行一个实例。  2.关键代码段实现线程的同步:类似公用电话亭,只有当电话亭里面没人了,其它人才可以再进去打电话。用了4个函数,这种方法比较简单!但缺点是如果使用了多少关键代码码,容易赞成线程的死锁3.线程死锁,用关键代码示例,用了两个临界区对象,实战中要注意避免这种错误!4.使用异步套接字编写网络聊天室  1)加载套接字库,进行版本协商,包含头文件,链接库文件,这次请示的是2.2版本!  2)在类CChatDlg中增加一个成员变量m_socket,在析构函数中释放这个变量  3)利用WSASocket()创建套接字(数据报类型的UDP型的)  4)然后调用WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ)为网络事件定义消息!此时如果发生FD_READ消息,系统会发送UM_SOCK消息给应用程序!程序并不会阻塞在这儿了!  以上是在BOOL CChatDlg::OnInitDialog()完成  5)然后完成消息响应!  头文件中:#define UM_SOCK  WM_USER+1afx_msg void OnSock(WPARAM,LPARAM);   源文件中:    ON_MESSAGE(UM_SOCK,OnSock)    实现消息响应函数:void CChatDlg::OnSock(WPARAM wParam,LPARAM lParam){switch(LOWORD(lParam)){case FD_READ:  WSABUF wsabuf;  wsabuf.buf=new char[200];  wsabuf.len=200;  DWORD dwRead;  DWORD dwFlag=0;  SOCKADDR_IN addrFrom;  int len=sizeof(SOCKADDR);  CString str;  CString strTemp;  HOSTENT *pHost;  if(SOCKET_ERROR==WSARecvFrom(m_socket,&wsabuf,1,&dwRead,&dwFlag,      (SOCKADDR*)&addrFrom,&len,NULL,NULL))  {   MessageBox("接收数据失败!");   return;  }  pHost=gethostbyaddr((char*)&addrFrom.sin_addr.S_un.S_addr,4,AF_INET);  //str.Format("%s说 :%s",inet_ntoa(addrFrom.sin_addr),wsabuf.buf);  str.Format("%s说 :%s",pHost->h_name,wsabuf.buf);  str+="\r\n";  GetDlgItemText(IDC_EDIT_RECV,strTemp);  str+=strTemp;  SetDlgItemText(IDC_EDIT_RECV,str);  break;}}OK!      6)完成数据发送的功能!      void CChatDlg::OnBtnSend() {// TOD Add your control notification handler code hereDWORD dwIP;CString strSend;WSABUF wsabuf;DWORD dwSend;int len;CString strHostName;SOCKADDR_IN addrTo;HOSTENT* pHost;if(GetDlgItemText(IDC_EDIT_HOSTNAME,strHostName),strHostName==""){  ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);  addrTo.sin_addr.S_un.S_addr=htonl(dwIP);}else{  pHost=gethostbyname(strHostName);  addrTo.sin_addr.S_un.S_addr=*((DWORD*)pHost->h_addr_list[0]);}addrTo.sin_family=AF_INET;addrTo.sin_port=htons(6000); GetDlgItemText(IDC_EDIT_SEND,strSend);len=strSend.GetLength();wsabuf.buf=strSend.GetBuffer(len);wsabuf.len=len+1; SetDlgItemText(IDC_EDIT_SEND,""); if(SOCKET_ERROR==WSASendTo(m_socket,&wsabuf,1,&dwSend,0,   (SOCKADDR*)&addrTo,sizeof(SOCKADDR),NULL,NULL)){  MessageBox("发送数据失败!");  return;}}       7)完成将主机名转换为IP地址的功能,以前将IP地址转换为主机名的功能嘿嘿,单线程的聊天室创建完毕!性能并且非常出色!

阅读(2149) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册