好久没有用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 于南昌