CSocket从 CAsyncSocket比派生,继承其 Windows 套接字 API 的封装,表示较高级别的抽象 CAsyncSocket 对象
AfxSocketInit() 这个函数,在使用CSocket前一定要先调用该函数,否则使用CSocket会出错;并且该函数还有一个重要的使用方式,
就是在某个线程下使用 CSocket 前一定要调用,就算主线程调用了该函数,在子线程下使用 CSocket 也要先调用该函数,要不会出错.
Create 方法已经包含了 Bind 方法,如果是以 Create 方法初始化的前提下不能再调用 Bind ,要不一定出错。
1 CSocket srvSocket, connSocket; 2 //最好不要使用srvSocket.Create创建,因为容易会出现10048错误 3 if (!srvSocket.Socket()) 4 { 5 AfxMessageBox(_T("Socket Create Faild!")); 6 return 1; 7 } 8 9 BOOL bOptVal = TRUE; 10 int bOptLen = sizeof(BOOL); 11 //设置Socket的选项, 解决10048错误必须的步骤 12 srvSocket.SetSockOpt(SO_REUSEADDR, (void *)&bOptVal, bOptLen, SOL_SOCKET); 13 //绑定端口 14 if (!srvSocket.Bind(8090)) 15 { 16 AfxMessageBox(_T("Bind Create Faild!")); 17 } 18 //监听 19 if(!srvSocket.Listen(10)) 20 { 21 AfxMessageBox(_T("Listen Create Faild!")); 22 return 1; 23 } 24 while(ServerStatus) 25 { 26 //接收外部连接 27 if(!srvSocket.Accept(connSocket)) 28 { 29 continue; 30 } 31 else 32 { 33 char szRecvMsg[256] = {0}; 34 char szOutMsg[256] = {0}; 35 //接收客户端内容:阻塞 36 connSocket.Receive(szRecvMsg, 256); 37 sprintf_s(pInfo->recvMsg,"Receive data = %s",szRecvMsg); 38 39 //发送内容给客户端 40 connSocket.Send("Have Receive The Msg", 50); 41 sprintf_s(pInfo->sendMsg,"Have Receive The Msg"); 42 ::PostMessage(pInfo->hWnd,WM_INFO,(WPARAM)pInfo,0); 43 //关闭 44 connSocket.Close(); 45 } 46 } 47 //关闭 48 srvSocket.Close(); 49 connSocket.Close();
AfxBeginThread 调用此函数以创建新线程。
1 CWinThread* AfxBeginThread( 2 AFX_THREADPROC pfnThreadProc, 3 LPVOID pParam, 4 int nPriority = THREAD_PRIORITY_NORMAL, 5 UINT nStackSize = 0, 6 DWORD dwCreateFlags = 0, 7 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 8 ); 9 CWinThread* AfxBeginThread( 10 CRuntimeClass* pThreadClass, 11 int nPriority = THREAD_PRIORITY_NORMAL, 12 UINT nStackSize = 0, 13 DWORD dwCreateFlags = 0, 14 LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 15 );
pfnThreadProc
指向工作线程的控件函数。 不能为 NULL。 必须对此函数声明如下:
UINT __cdecl MyControllingFunction( LPVOID pParam );
pParam
参数传递到控制函数,如 pfnThreadProc 中的参数至函数声明所示。
返回值:如果失败,指针则指向新建的线程对象或 NULL。
AfxBeginThread 的第一个窗体创建辅助线程。 第二个窗体创建了一个可用作用户界面线程或辅助线程的线程。
1 struct threadInfo 2 { 3 char recvMsg[256]; 4 char sendMsg[256]; 5 HWND hWnd; //主窗口句柄,用于消息的发送 6 }; 7 8 CWinThread *m_pThread; 9 threadInfo m_Info; 10 11 memset(m_Info.recvMsg,0,sizeof(m_Info.recvMsg)); 12 memset(m_Info.sendMsg,0,sizeof(m_Info.sendMsg)); 13 m_Info.hWnd = m_hWnd; 14 15 m_pThread = AfxBeginThread(ThreadProc,&m_Info); 16 17 UINT __cdecl ThreadProc(LPVOID pParam) 18 { 19 threadInfo *pInfo=(threadInfo*)pParam; 20 .... 21 return 0; 22 }
CWnd::PostMessage 在窗口的消息队列将消息然后返回,而不等待对应的窗口处理消息。
PostMessage:不需要指定接收消息的窗口,但是消息只能发往本窗口
::PostMessage:需要指定接收消息的窗口,但是消息可以发往任意窗口
BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); message 指定要发送的消息。 wParam 指定附加信息信息。 此参数内容取决于发送的消息。 lParam 指定附加信息信息。 此参数内容取决于发送的消息。 返回值:非零,如果消息已传递;否则为0。
//所有自定义消息都是以WM_USER消息为基础加上一个任意的自然数来表示的,推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。
1 #define WM_INFO WM_USER+100 2 3 ON_MESSAGE(WM_INFO, &CStockServerDlg::OnInfo) //自定义消息 4 5 ::PostMessage(pInfo->hWnd,WM_INFO,(WPARAM)pInfo,0); 6 7 afx_msg LRESULT CStockServerDlg::OnInfo(WPARAM wParam, LPARAM lParam) 8 { 9 threadInfo *psInfo=(threadInfo*)wParam; //传的是一个结构体的指针 10 m_edit1 = psInfo->recvMsg; 11 m_edit2 = psInfo->sendMsg; 12 UpdateData(FALSE); 13 14 return 0; 15 }
动态添加菜单:
CMenu m_menu; //public 变量
m_menu.LoadMenuW(IDR_MENU1);
SetMenu(&m_menu);
源码code下载:
1 http://download.csdn.net/detail/u011845833/8388055