【网络编程】之七、select聊天室

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

原文地址:https://www.cnblogs.com/java20130723/p/3211406.html