www.pudn.com > TestIPMSG.rar > ChatWidnowDlg.cpp
// ChatWidnowDlg.cpp : implementation file // #include "stdafx.h" #include "TestIPMSG.h" #include "ChatWidnowDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CChatWidnowDlg dialog extern vectorg_AcceptClient; /// CChatWidnowDlg::CChatWidnowDlg(CWnd* pParent /*=NULL*/) : CDialog(CChatWidnowDlg::IDD, pParent), m_bDFirst(FALSE), m_bLFirst(FALSE), m_chatPort(0), m_bNet(FALSE), m_serialNum(0), m_bNetPort(FALSE) { //{{AFX_DATA_INIT(CChatWidnowDlg) m_sMsg = _T(""); m_ClientInfoLB = _T(""); //}}AFX_DATA_INIT } void CChatWidnowDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CChatWidnowDlg) DDX_Text(pDX, IDC_EDIT1, m_sMsg); DDX_Text(pDX, IDC_EDIT2, m_ClientInfoLB); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CChatWidnowDlg, CDialog) //{{AFX_MSG_MAP(CChatWidnowDlg) ON_BN_CLICKED(IDOK, OnSendMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatWidnowDlg message handlers BOOL CChatWidnowDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here DWORD dwNameLen = sizeof(m_szMyLocalName); GetUserName((LPTSTR)m_szMyLocalName,&dwNameLen); if ( m_curChatName != NULL) { char curDescripChat[80]; sprintf(curDescripChat,"你正在和%s聊天",m_curChatName); if ( m_curChatName != NULL ) SetWindowText(_T(curDescripChat)); } if ( m_bNet == TRUE ) { char lpszHeader[NET_TRANSMIT_BUFFER]; char lpszChatContent[NET_TRANSMIT_BUFFER]; ChatDataInfo *chatDataInfo = (ChatDataInfo *)m_firstContent; sprintf(lpszHeader,"%s:%s",chatDataInfo->m_clientName,chatDataInfo->m_curSysTimer); sprintf(lpszChatContent,"%s",chatDataInfo->m_curChatData); ShowText(lpszHeader,lpszChatContent); } StartChatServerThread(); ///// return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CChatWidnowDlg::SendDataToClient(char *sendBuf) { if ( sendBuf != NULL ) { vector ::iterator ts; for ( ts = g_AcceptClient.begin(); ts != g_AcceptClient.end(); ts ++ ) { if ( strcmp(ts->m_loginName,m_curChatName) == 0 ) { break; } } if ( ts == g_AcceptClient.end() ) { AfxMessageBox("对方已经下线!"); return; } SOCKADDR_IN addrSend; addrSend.sin_addr.S_un.S_addr = inet_addr(ts->m_ClientIPAddr); addrSend.sin_family = AF_INET; addrSend.sin_port = htons(NET_CHAT_PORT + m_chatPort); int isend = sendto(m_ChatServerSocket,sendBuf,NET_TRANSMIT_BUFFER,0,(struct sockaddr FAR *)&addrSend,sizeof(SOCKADDR_IN)); DWORD dwRet = ::WaitForSingleObject(m_hSend,200); if ( dwRet == WAIT_TIMEOUT || isend == SOCKET_ERROR ) { addrSend.sin_port = htons(NET_CHAT_WINDOW_PORT); isend = sendto(m_ChatServerSocket,sendBuf,NET_TRANSMIT_BUFFER,0,(struct sockaddr FAR *)&addrSend,sizeof(SOCKADDR_IN)); if ( isend == SOCKET_ERROR ) { AfxMessageBox("发送失败!"); return; } } if ( dwRet == WAIT_OBJECT_0 ) ResetEvent(m_hSend); } } void CChatWidnowDlg::RecvDataFromClient() { SOCKADDR_IN addrfrom; char RecvChatInfo[NET_TRANSMIT_BUFFER]; int addrLen = sizeof (SOCKADDR_IN); int iRecv = recvfrom(m_ChatServerSocket,RecvChatInfo,sizeof(RecvChatInfo),0,(struct sockaddr FAR *)&addrfrom,&addrLen); if ( iRecv == SOCKET_ERROR ) { TRACE("接收失败!"); return; } ProRecvData(RecvChatInfo,addrfrom); } void CChatWidnowDlg::SendQueryChatCommand(char *sendBuf) { ChatDataInfo *DataInfo = (ChatDataInfo *)sendBuf; if ( sendBuf != NULL ) { vector ::iterator ts; for ( ts = g_AcceptClient.begin(); ts != g_AcceptClient.end(); ts ++ ) { if ( strcmp(ts->m_loginName,m_curChatName) == 0 ) { break; } } if ( ts == g_AcceptClient.end() ) { AfxMessageBox("对方已经下线!"); return; } SOCKADDR_IN addrSend; addrSend.sin_addr.S_un.S_addr = inet_addr(ts->m_ClientIPAddr); addrSend.sin_family = AF_INET; addrSend.sin_port = htons(NET_CHAT_PORT + m_chatPort); int isend = sendto(m_ChatServerSocket,sendBuf,NET_TRANSMIT_BUFFER,0,(struct sockaddr FAR *)&addrSend,sizeof(SOCKADDR_IN)); DWORD dwRet = ::WaitForSingleObject(m_hSend,3000); if ( dwRet == WAIT_TIMEOUT || isend == SOCKET_ERROR ) { addrSend.sin_port = htons(NET_CHAT_WINDOW_PORT); isend = sendto(m_ChatServerSocket,sendBuf,NET_TRANSMIT_BUFFER,0,(struct sockaddr FAR *)&addrSend,sizeof(SOCKADDR_IN)); if ( isend == SOCKET_ERROR ) { AfxMessageBox("发送失败!"); return; } ResetEvent(m_hSend); } if ( dwRet == WAIT_OBJECT_0 ) ResetEvent(m_hSend); } } BOOL CChatWidnowDlg::InitChatServerSocket() { int istat = WSAStartup(MAKEWORD(2,2),&m_wsa); if ( istat != 0 ) { AfxMessageBox("加载winsock失败!"); return FALSE; } m_ChatServerSocket = socket(AF_INET,SOCK_DGRAM,0); if ( m_ChatServerSocket == INVALID_SOCKET ) { AfxMessageBox("创建socket失败!"); return FALSE; } GetHostIP(m_dwLocalIPAddr); if ( m_bNetPort == TRUE ) { GetLocalPort(m_chatPort); m_bNetPort = FALSE; } else { GetChatPort(m_chatPort); } m_ChatServerIpAddr.sin_addr.S_un.S_addr = m_dwLocalIPAddr; m_ChatServerIpAddr.sin_family = AF_INET; m_ChatServerIpAddr.sin_port = htons(NET_CHAT_PORT + m_chatPort); BOOL bFlag = TRUE; int iset = setsockopt(m_ChatServerSocket,SOL_SOCKET,SO_REUSEADDR,(const char *)&bFlag,sizeof(BOOL)); int iError = WSAGetLastError(); if ( iset == SOCKET_ERROR ) { TRACE("setsockopting is falied"); } int ibind = bind(m_ChatServerSocket,(struct sockaddr FAR *) &m_ChatServerIpAddr,sizeof(SOCKADDR_IN)); if ( ibind == SOCKET_ERROR ) { AfxMessageBox("邦定socket失败!"); return FALSE; } return TRUE; } void CChatWidnowDlg::GetHostIP(DWORD &dwLocalIP) { struct hostent *thisHost; struct in_addr in; char hostName[80]; if ( gethostname(hostName,sizeof(hostName)) == SOCKET_ERROR ) { AfxMessageBox("取得本地主机名失败!"); return ; } if ( hostName != NULL ) thisHost = gethostbyname(hostName); int i = 0; while ( thisHost->h_addr_list[i] ) { in.S_un.S_addr = *(unsigned long *)thisHost->h_addr_list[i]; i++; } dwLocalIP = in.S_un.S_addr; } void CChatWidnowDlg::StartChatServerThread() { m_hSend = CreateEvent(NULL,TRUE,TRUE,NULL); ResetEvent(m_hSend); HANDLE hChatThread = CreateThread(NULL,0,ChatServerSocketThread,this,CREATE_SUSPENDED,&m_id); ResumeThread(hChatThread); } DWORD CChatWidnowDlg::ChatServerSocketThread(LPVOID lParam) { CChatWidnowDlg * chatDlg = (CChatWidnowDlg *)lParam; BOOL bIni = chatDlg->InitChatServerSocket(); if ( bIni == FALSE ) return 0L; chatDlg->FastToClient(); FD_SET fdR; struct timeval timeouts; timeouts.tv_sec = 1; timeouts.tv_usec = 0; while ( true ) { FD_ZERO(&fdR); FD_SET(chatDlg->m_ChatServerSocket,&fdR); switch( select(chatDlg->m_ChatServerSocket + 1, &fdR , NULL ,NULL ,&timeouts) ) { case -1: break; case 0: break; default: if ( FD_ISSET(chatDlg->m_ChatServerSocket,&fdR) ) chatDlg->RecvDataFromClient(); break; } Sleep(1); } return 0L; } void CChatWidnowDlg::OnSendMsg() { // TODO: Add your control notification handler code here //UpdateData(true); char chatSendBuff[NET_TRANSMIT_BUFFER]; CString curChatContent; SYSTEMTIME sysTimer; GetLocalTime(&sysTimer); ChatDataInfo *ChatInfo = new ChatDataInfo; memset(ChatInfo,0,sizeof(ChatDataInfo)); ChatInfo->m_szFlag = (char )0x81; ChatInfo->m_serialNum = m_serialNum ++ ; sprintf(ChatInfo->m_clientName,"%s",m_szMyLocalName); sprintf(ChatInfo->m_curSysTimer,"%u-%u-%u %u:%2u:%2u", sysTimer.wYear, sysTimer.wMonth, sysTimer.wDay, sysTimer.wHour, sysTimer.wMinute, sysTimer.wSecond ); GetDlgItem(IDC_EDIT1)->GetWindowText(m_sMsg); int iMsgLen = m_sMsg.GetLength(); char ContentBuff[NET_TRANSMIT_BUFFER]; strcpy(ContentBuff,m_sMsg.GetBuffer(iMsgLen)); sprintf(ChatInfo->m_curChatData,"%s",ContentBuff); int lpbuflen = sprintf(chatSendBuff,"%s:%u-%u-%u %u:%2u:%2u", m_szMyLocalName, sysTimer.wYear, sysTimer.wMonth, sysTimer.wDay, sysTimer.wHour, sysTimer.wMinute,//szMinute, sysTimer.wSecond//szSecond ); curChatContent = curChatContent + chatSendBuff + "\n\r" + m_sMsg; if ( m_bDFirst == TRUE ) { SendQueryChatCommand((char*)ChatInfo); } else SendDataToClient((char*)ChatInfo); //// ShowText(chatSendBuff,ContentBuff); m_sMsg.ReleaseBuffer(); m_sMsg == _T(""); delete ChatInfo; GetDlgItem(IDC_EDIT1)->SetWindowText(""); } void CChatWidnowDlg::GetChatPort(unsigned short &uPort) { vector ::iterator ts; for ( ts = g_AcceptClient.begin(); ts != g_AcceptClient.end(); ts ++ ) { if ( strcmp(ts->m_loginName,m_curChatName) == 0 ) { break; } } if ( ts == g_AcceptClient.end() ) { AfxMessageBox("对方已经下线!"); return; } DWORD dwClientIP = inet_addr(ts->m_ClientIPAddr); uPort = (((dwClientIP)>>24)&0x000000ff) + (((m_dwLocalIPAddr)>>24)&0x000000ff); } void CChatWidnowDlg::ProRecvData(char *RecvData,SOCKADDR_IN saddrClient) { char szFlag = *RecvData; switch( (BYTE)szFlag ) { case 0x81: { char lpszHeader[NET_TRANSMIT_BUFFER]; char lpszChatContent[NET_TRANSMIT_BUFFER]; ChatDataInfo *chatDataInfo = (ChatDataInfo *)RecvData; if ( chatDataInfo->m_serialNum == m_serialNum-1 ) SetEvent(m_hSend); sprintf(lpszHeader,"%s:%s",chatDataInfo->m_clientName,chatDataInfo->m_curSysTimer); sprintf(lpszChatContent,"%s",chatDataInfo->m_curChatData); ShowText(lpszHeader,lpszChatContent); //// AckInfo * ackInfo = new AckInfo; ackInfo->m_szFlag = (char )0x88; ackInfo->m_serialNum = chatDataInfo->m_serialNum; int isend = sendto(m_ChatServerSocket,(char*)ackInfo,NET_TRANSMIT_BUFFER,0,(struct sockaddr FAR *)&saddrClient,sizeof(SOCKADDR_IN)); if ( isend == SOCKET_ERROR ) { TRACE("发送ACK失败!"); } delete ackInfo; break; } case 0x88: { AckInfo *ackInfo = ( AckInfo *)RecvData; if ( ackInfo->m_serialNum == m_serialNum-1 ) { SetEvent(m_hSend); } break; } default: break; } } void CChatWidnowDlg::ShowText(char *lpszNT, char *lpszMsg) { if ( m_bDFirst == TRUE ) { m_ClientInfoLB = m_ClientInfoLB + lpszNT; m_bDFirst = FALSE ; } else if ( m_bNet == TRUE ) { m_ClientInfoLB = m_ClientInfoLB + lpszNT; m_bNet = FALSE; } else if ( m_bLFirst = TRUE ) { m_ClientInfoLB = m_ClientInfoLB + lpszNT; m_bLFirst = FALSE; } else m_ClientInfoLB = m_ClientInfoLB + "\r\n" + lpszNT; GetDlgItem(IDC_EDIT2)->SetWindowText((LPCSTR)m_ClientInfoLB); CEdit *pEdit; pEdit=(CEdit *)GetDlgItem(IDC_EDIT2); int i=pEdit->GetLineCount(); pEdit->LineScroll(i,0); m_ClientInfoLB = m_ClientInfoLB + "\r\n" + lpszMsg + "\r\n"; GetDlgItem(IDC_EDIT2)->SetWindowText((LPCSTR)m_ClientInfoLB); pEdit = (CEdit *) GetDlgItem(IDC_EDIT2); i = pEdit->GetLineCount(); pEdit->LineScroll(i,0); } void CChatWidnowDlg::GetLocalPort(unsigned short &usNetPort) { vector ::iterator ts; for ( ts = g_AcceptClient.begin(); ts != g_AcceptClient.end(); ts ++ ) { if ( strcmp(ts->m_loginName,m_curChatName) == 0 ) { break; } } if ( ts == g_AcceptClient.end() ) { AfxMessageBox("对方已经下线!"); return ; } DWORD dwClientIP = inet_addr(ts->m_ClientIPAddr); usNetPort = ((dwClientIP>>24)&0x000000ff) + ((m_dwLocalIPAddr>>24)&0x000000ff); } void CChatWidnowDlg::FastToClient() { if ( m_bLFirst == TRUE ) { char lpszHeader[NET_TRANSMIT_BUFFER]; char lpszChatContent[NET_TRANSMIT_BUFFER]; SYSTEMTIME sysTimer; GetLocalTime(&sysTimer); ChatDataInfo *ChatInfo = new ChatDataInfo; ChatInfo->m_szFlag = (char )0x81; ChatInfo->m_serialNum = m_serialNum ++ ; sprintf(ChatInfo->m_clientName,"%s",m_szMyLocalName); sprintf(ChatInfo->m_curSysTimer,"%u-%u-%u %u:%2u:%2u", sysTimer.wYear, sysTimer.wMonth, sysTimer.wDay, sysTimer.wHour, sysTimer.wMinute, sysTimer.wSecond ); sprintf(ChatInfo->m_curChatData,"%s",m_firstContent); sprintf(lpszHeader,"%s:%s",ChatInfo->m_clientName,ChatInfo->m_curSysTimer); sprintf(lpszChatContent,"%s",ChatInfo->m_curChatData); ShowText(lpszHeader,lpszChatContent);///// SendQueryChatCommand((char*)ChatInfo); delete ChatInfo; } }