• 【网络编程】之七、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 于南昌

  • 相关阅读:
    JavaScript getElementByID() not working
    [转] 从此不再惧怕URI编码:JavaScript及C# URI编码详解
    win 8.1 突然没有了声音 -- 解决办法
    升级打怪第一天 -------字符串重复
    Flex布局
    HTML 的全局事件属性
    CSS position 相对定位和绝对定位
    将1100秒转换为分秒格式
    新手小白的上路之旅
    谈谈我对Manacher算法的理解
  • 原文地址:https://www.cnblogs.com/java20130723/p/3211406.html
Copyright © 2020-2023  润新知