企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
**AfxSocketInit** ```c++ 调用 CWinApp::InitInstance 中的重写函数初始化此 Windows 套接字。 格式: BOOL AfxSocketInit( WSADATA* lpwsaData = NULL ); 返回值: 如果函数成功执行,则返回非零值,否则为0。 参数: lpwsaData 指向WSADATA结构的指针。如果lpwsaData不等于NULL,那么调用::WSAStartup将填充WSADATA结构。这个函数同时也保证在应用程序结束之前调用::WSACleanup。 说明: 在你重载的CWinApp::InitInstance函数中调用这个函数以初始化WindowsSockets。 在调用 AfxSocketInit() 之前,需要包含 afxsock.h 头文件。 例子: if ( !AfxSocketInit() ) { AfxMessageBox( _T("Failed to Initialize Sockets"), MB_OK | MB_ICONSTOP); return FALSE; } ``` 1.初始化socket ```c++ CDialogEx::OnInitDialog(); BOOL b = m_sock.Create(8811,SOCK_DGRAM); DWORD nErr = GetLastError(); SetDlgItemText(IDC_IP,L"192.168.1.124"); SetDlgItemText(IDC_PORT,L"8811"); //可以通过工具-》错误查找,找到错误代码提示 if (WSANOTINITIALISED == nErr) //1009 { AfxMessageBox(L"Successful WSAStartup not yet performed."); } if (WSAEADDRINUSE == nErr) // { AfxMessageBox(L"the specific address is committed"); } ``` 2.点击发送 ```c++ void CUdpDlg::OnBnClickedOk() { //CDialogEx::OnOK(); CString str; GetDlgItemText(IDC_INPUT,str); if (str.IsEmpty()) { AfxMessageBox(L"不能发送空文字!");return; } CString szIP; GetDlgItemText(IDC_IP,szIP); m_sock.SendTo(str,str.GetLength(),8811,szIP); } ``` 3.如果要在窗体上输出接收的字符串 则要定义CSocket派生类 (问题:只接收到一个字符 ) ```c++ void CSockN::OnReceive(int nErrorCode) { // TODO: 在此添加专用代码和/或调用基类 CString szIP; UINT nPort; wchar_t s[512]; int nLen = ReceiveFrom(s,sizeof(s),szIP,nPort); s[nLen] = 0; /*size_t len = strlen(s) + 1; size_t converted = 0; wchar_t *WStr; WStr=(wchar_t*)malloc(len*sizeof(wchar_t)); mbstowcs_s(&converted, WStr, len, s, _TRUNCATE);*/ CUdpDlg *pDlg = (CUdpDlg*)AfxGetMainWnd();//获取主对话框的句柄 pDlg->OnReceive(s,szIP); CSocket::OnReceive(nErrorCode); } ``` 4.最后把接收到的值输出到窗口 (问题:直接收到一个字符执行到 GetWindowTextLengthW()会终止程序) ```c++ void CUdpDlg::OnReceive(LPCWSTR szText, LPCWSTR szIP) { CString str = szIP; str += "\r\n"; str += szText; str += "\r\n"; int nLen = m_his.GetWindowTextLengthW();//获取当前文字有多长 m_his.SetSel(nLen,-1);//尾部 m_his.ReplaceSel(str);//插入到最后 } ``` **问题解决** 1.Receivefrom只接收到一个字符 ``` //在sendTod之前把数据格式转化为 LPSTR(char*) void CSocketClientDlg::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 //CDialogEx::OnOK(); CString str; GetDlgItemText(IDC_INPUT,str); if (str.IsEmpty()){ AfxMessageBox(_T("不能发送空消息!"));return; } CString szIP; CString nPort; GetDlgItemText(IDC_IP,szIP); GetDlgItemText(IDC_PORT,nPort); USES_CONVERSION; LPSTR pBuf = W2A(str); int i = strlen(pBuf); m_sock.SendTo(pBuf,i,8111,szIP); } //在CSock派生类,收里面吧接收的数据用 char*接收 void CSockU::OnReceive(int nErrorCode) { // TODO: 在此添加专用代码和/或调用基类 char recBuf[1024]={0}; CString szIP; UINT nPort; int len = ReceiveFrom(recBuf,sizeof(recBuf),szIP,nPort); ///接受的数据 recBuf[len] = 0; CSocketClientDlg* pDlg = (CSocketClientDlg*) AfxGetMainWnd(); CString strtest; strtest = recBuf; pDlg->OnReceive(strtest,szIP); CSocket::OnReceive(nErrorCode); } ```` ***** 只要在发送时将str通过 **WideCharToMultiByte** 函数转化为MBCS编码方式就行了 Unicode 转MBCS ```c++ //1.使用WideCharToMultiByte // 假设已经有了一个Unicode 串 wszSomeString... char szANSIString [MAX_PATH]; WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); //2.使用W2A宏来实现(可能会出现栈溢出,不要在循环中使用,最好是单独定义一个函数来实现。) #include <atlconv.h> USES_CONVERSION; pTemp=W2A(wszSomeString); ``` MBCS转Unicode ```c++ //1.使用MultiByteToWideChar char *szProgID = "MAPI.Folder"; WCHAR szWideProgID[128]; CLSID clsid; long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID)); szWideProgID[lLen] = '/0'; //2.通过A2W宏来实现(可能会出现栈溢出,不要在循环中使用,最好是单独定义一个函数来实现。) #include <atlconv.h> USES_CONVERSION; CLSIDFromProgID( A2W(szProgID),&clsid); //3.通过L这个宏来实现 CLSIDFromProgID( L"MAPI.Folder",&clsid); ``` https://bbs.csdn.net/topics/380215603 *****