zoukankan      html  css  js  c++  java
  • C++聊天室(孙鑫MFC总结)

    老师的作业,让做一个局域网聊天室!看了孙鑫的视频!自己也简单的实现了一下!感觉挺棒的!

    一个中心-----"练习"

    下面贴出自己的简单理解,告诉自动掠过,,,,,,,,,

    聊天室基于UDP协议,

    1.套接字初始化

    AfxSocketInit()函数初始化 

    1     if(!AfxSocketInit())
    2 {
    3 AfxMessageBox("加载套接字失败库!");
    4 return FALSE;
    5 }
     

     套接字初始化完成,当然我们得在预编译头文件里面将AfxSocketInit()所需的头文件包含进来,否则他不认识的!

    1 #include <afxsock.h>  //stdfax.h中的
    BOOL CNetworkDlg::InintScoket()
    {
    	m_scoket=socket(AF_INET,SOCK_DGRAM,0); //自己要做的工作-----定义私有变量成员
    	if(INVALID_SOCKET==m_scoket)
    	{
    		MessageBox("套接字创建失败");
    		return FALSE;
    	}
    		SOCKADDR_IN addrSock;
    		addrSock.sin_family=AF_INET;
    		addrSock.sin_port=htons(6000);
    		addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY) ;
    		int reval;
    		reval=bind(m_scoket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
    		if(SOCKET_ERROR==reval)
    		{
    			closesocket(m_scoket);
    			MessageBox("绑定失败!");
    			return FALSE;
    		}
    	
    	return TRUE;
    
    	
    }
    

      这样我们就可以在OnInitDialog()里面调用了;

    2.接收端 

    接收端由于要处理实时消息,所以单独做出一个线程来处理!我们来看一下MSDN的解释:

    CreateThread
    The CreateThread function creates a thread to execute within the virtual address space of the calling process. 
    
    To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function. 
    
    HANDLE CreateThread(
      LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
      DWORD dwStackSize,                        // initial stack size
      LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
      LPVOID lpParameter,                       // thread argument
      DWORD dwCreationFlags,                    // creation option
      LPDWORD lpThreadId                        // thread identifier
    );
    

    以上函数,各个参数我就这里不解释了(具体我其实不知道看孙鑫十五课)第三个参数是我们关注的对象!只能传进去一个参数!然而我们想处理的却有两个:套接字和窗口句柄!

    我们注意到这是一个指针!所以我们做一个结构体将其作为指针传进得到两个值

    1 struct RECEPARAM
    2 {
    3 SOCKET socket;
    4 HWND hwnd;
    5 };

    然后放到OnInitDialog()调用CreateThread()得到其句柄

    1     RECEPARAM *pReceParam=new RECEPARAM;
    2 pReceParam->socket=m_scoket;
    3 pReceParam->hwnd=m_hWnd;
    4 HANDLE hThread=CreateThread(NULL,0,ReceProc,(LPVOID)pReceParam,0,NULL); //注意到Rece是线程创建的函数!
    5 CloseHandle(hThread);


    下面写先从创建函数!ReceProc();

     1 DWORD WINAPI  CNetworkDlg::ReceProc(LPVOID lpParameter)
    2 {
    3 SOCKET sock=((RECEPARAM*)lpParameter)->socket;
    4 HWND hwnd=((RECEPARAM*)lpParameter)->hwnd;
    5
    6 //接收数据
    7 SOCKADDR_IN addr_form;
    8 int len=sizeof(SOCKADDR);
    9 char recBuf[200];
    10 char tempBuf[300];
    11
    12 int retval;
    13 while(TRUE)
    14 {
    15 retval=recvfrom(sock,recBuf,200,0,(SOCKADDR*)&addr_form,&len);
    16 if ( SOCKET_ERROR ==retval)
    17 {
    18 break;
    19 }
    20 sprintf(tempBuf,"%s 说: %s",inet_ntoa(addr_form.sin_addr),recBuf);
    21 ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
    22 }
    23
    24
    25 return 0;
    26 }

    整个程序运行起来,线程就不断的跑了(while(true))!

    当来消息时,怎么办呢?

    下面是消息处理函数:

    1     afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam); //声明为私有函数
     1  void CNetworkDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
    2 {
    3
    4 CString str=(char*)lParam;
    5 CString strTemp;
    6 GetDlgItemText(IDC_EDIT_RECE,strTemp);
    7 str+="\r\n";
    8 str+=strTemp;
    9 SetDlgItemText(IDC_EDIT_RECE,str);
    10 }

    这样就能处理了.......

    下面类看一下界面吧(开始就该设计好的)

    当要点击发送时要完成的工作:获取IP,保存并传入内容,送过去让线程捕获!

    双击界面“发送”

     1 void CNetworkDlg::OnBtnSend() 
    2 {
    3 // TODO: Add your control notification handler code here
    4 DWORD dwip;
    5
    6 ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS2))->GetAddress(dwip);
    7 SOCKADDR_IN addrTo;
    8 addrTo.sin_family=AF_INET;
    9 addrTo.sin_port=htons(6000);
    10 addrTo.sin_addr.S_un.S_addr=htonl(dwip) ;
    11
    12 CString strSend;
    13 GetDlgItemText(IDC_EDIT2,strSend);
    14 sendto(m_scoket,strSend,strSend.GetLength()+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
    15 SetDlgItemText(IDC_EDIT2,"");
    16
    17 }


    好了,发送过去了,正在跑动的线程一捕获,立马显示给编辑框!

    我实验了一下,有个bug,看不到自己的发送内容(明明保存了内容怎么就消失了呢?)

    自己给自己发可以,两台电脑上有问题!摸索中,,,,,,,,



  • 相关阅读:
    福尔摩斯的约会 (20)
    数素数 (20)
    STL源码分析-priority_queue
    STL源码分析-bitset
    STL源码分析-rbtree
    STM32自动生成精美图案
    STL源码分析-function
    STL源码分析-list
    STL源码分析-iterator
    STL源码分析-traits
  • 原文地址:https://www.cnblogs.com/leisure/p/2252117.html
Copyright © 2011-2022 走看看