好久没有用MFC 来写代码了,手都生疏了,悲剧啊,好多API 都去查的 哎~~~
好了 下面把 我们聊天室的代码贴出:
select函数封装:
BOOL CserverDlg::Select_Server(SOCKET sock, int nTime /* = 100 */, BOOL bRead /* = TRUE */) { fd_set fdset; timeval tv; FD_ZERO(&fdset); FD_SET(sock, &fdset); nTime = nTime > 1000 ? 1000 : nTime; tv.tv_sec = 0; tv.tv_usec = nTime; int iRet = 0; if ( bRead ) { iRet = select(0, &fdset, NULL , NULL, &tv); }else{ iRet = select(0, NULL , &fdset, NULL, &tv); } if(iRet <= 0) { return FALSE; } else if (FD_ISSET(sock, &fdset)){ return TRUE; } return FALSE; }
下面是线程函数,分别是服务器和客户端的:
static UINT __cdecl ThreadProc(LPVOID pParam);
UINT CserverDlg::ThreadProc(LPVOID lpParameter ) { ASSERT(lpParameter); CserverDlg *lthis = (CserverDlg*)lpParameter; sockaddr_in clientAddr = {0}; WSADATA wsaData; WORD sockVersion = MAKEWORD (2, 0); ::WSAStartup(sockVersion, &wsaData); lthis ->m_sSock = INVALID_SOCKET; lthis ->m_sSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (lthis ->m_sSock == INVALID_SOCKET) { AfxMessageBox("error"); ::WSACleanup(); return TRUE; } sockaddr_in ser; ser.sin_family = AF_INET; ser.sin_port = htons(8888); ser.sin_addr.S_un.S_addr = INADDR_ANY; if (::bind(lthis->m_sSock, (LPSOCKADDR)&ser, sizeof(ser)) == SOCKET_ERROR) { AfxMessageBox("error"); WSACleanup(); return TRUE; } if (listen(lthis->m_sSock, 2) == SOCKET_ERROR) { AfxMessageBox("error"); WSACleanup(); return TRUE; } int nclientAddr = sizeof(clientAddr); lthis ->m_sClient = accept(lthis->m_sSock, (SOCKADDR*)&clientAddr, &nclientAddr); if (lthis->m_sClient == INVALID_SOCKET) { AfxMessageBox("error"); return TRUE; } while(TRUE) { if (lthis->Select_Server(lthis->m_sClient) == TRUE) { TCHAR recvMeg[1024] = {0}; int re = recv(lthis->m_sClient, (char*)recvMeg, 1024, 0); if (re > 0) { recvMeg[re] = '\n'; lthis->recvMeg(recvMeg); } else { lthis->recvMeg("客户端下线"); break; } } Sleep(500); } if (lthis->m_sClient != INVALID_SOCKET) { closesocket(lthis->m_sClient); } if (lthis->m_sSock != INVALID_SOCKET) { closesocket(lthis->m_sSock); } WSACleanup(); return TRUE; }
static UINT __cdecl ThreadProc(LPVOID pParam);
UINT CclientDlg::ThreadProc(LPVOID pParam) { ASSERT(pParam); CclientDlg* lthis = (CclientDlg*)pParam; WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 0); ::WSAStartup(sockVersion, &wsaData); lthis->m_Sock = INVALID_SOCKET; lthis->m_Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (lthis->m_Sock == INVALID_SOCKET) { AfxMessageBox("error"); return TRUE; } sockaddr_in serAdd; serAdd.sin_family = AF_INET; serAdd.sin_port = htons(8888); serAdd.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (connect(lthis->m_Sock, (sockaddr*)&serAdd, sizeof(serAdd)) == SOCKET_ERROR) { AfxMessageBox("error"); return TRUE; } while (TRUE) { TCHAR buff[1024] = {0}; if (lthis->Select_Server(lthis->m_Sock)) { int nrecv; nrecv = recv(lthis->m_Sock, buff, 1024, 0); if (nrecv > 0) { buff[nrecv] = '\n'; lthis->recvMeg(buff); } else { lthis->recvMeg("服务器终止"); break; } } Sleep(500); } if (lthis->m_Sock != INVALID_SOCKET) { closesocket(lthis->m_Sock); } WSACleanup(); return TRUE; }
void CserverDlg::OnBnClickedButsend() { // TODO: 在此添加控件通知处理程序代码 CString strsend; ASSERT(m_sClient != INVALID_SOCKET); GetDlgItemText(IDC_SEND, strsend); if (!strsend.IsEmpty() && Select_Server(m_sClient, 100, FALSE)) { send(m_sClient, strsend, strlen(strsend), 0); SetDlgItemText(IDC_SEND, ""); } }
完整代码下载
2012/8/28
jofranks 于南昌