?? datasocket.cpp
字號:
// DataSocket.cpp : implementation file
#include "stdafx.h"
#include "Server.h"
#include "MainFrm.h"
#include "..\\Common.h"
#include "DataSocket.h"
#include "ListenSocket.h"
#include "ServerDoc.h"
#include "ServerView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDataSocket
CDataSocket::CDataSocket(CAsyncSocket* pListenSock)
{
// m_pMainWnd = ((CListenSocket*)pListenSock)->GetMainWnd();
// 設(shè)定套接字選項
LINGER linger;
linger.l_onoff = 1;
linger.l_linger = 5000; // 等待5秒
SetSockOpt(SO_LINGER, (void*)&linger, sizeof(linger), SOL_SOCKET);
}
CDataSocket::~CDataSocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CDataSocket, CAsyncSocket)
//{{AFX_MSG_MAP(CDataSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0
/////////////////////////////////////////////////////////////////////////////
// CDataSocket member functions
void CDataSocket::OnReceive(int nErrorCode)
{
if (nErrorCode != 0) {
return;
}
// 查看數(shù)據(jù)包類型
WORD type = 0;
if (Receive((void*)&type, sizeof(type), 0) != sizeof(type)) {
TRACE0("unable to receive package type info.");
return;
}
switch (type)
{
case PACKAGE_LOGIN: // login infomation
OnReceiveLogin();
break;
case PACKAGE_LOGOUT:
OnReceiveLogout();
break;
case PACKAGE_MESSAGE: // message send to server
OnReceiveMessage();
break;
default:
break;
}
}
void CDataSocket::OnReceiveLogin()
{
LOGIN_INFO info;
if (Receive((void*)&info, sizeof(info), 0) != sizeof(info)) {
TRACE0("unable to receive user login infomation.");
return;
}
// 你可以在這里檢測用戶名和密碼的正確性, 為簡單起見, 我們在這里跳過
// 向其他用戶發(fā)送該用戶上線的消息
SOCKADDR_IN addrIn;
int addrLen = sizeof(SOCKADDR_IN);
if (!GetPeerName((SOCKADDR*)&addrIn, &addrLen)) {
TRACE0("Unable to get peer name.\n");
return;
}
USER_INFO userInfo;
memcpy(userInfo.name, info.name, strlen(info.name) + 1);
userInfo.port = addrIn.sin_port;
userInfo.addr = addrIn.sin_addr.s_addr;
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CServerDoc* pDoc = (CServerDoc*)pFrame->GetActiveDocument();
CServerView* pView = (CServerView*)pFrame->GetActiveView();
// 更新顯示消息
CString strMsg;
strMsg.Format(IDS_LOGIN, userInfo.name,
inet_ntoa(*(in_addr*)&userInfo.addr),
ntohs(userInfo.port));
pView->AppendMessage(strMsg);
// 向登錄用戶發(fā)送在線人員列表
pDoc->SendUserListTo(userInfo, this);
// 向所有用戶發(fā)送該用戶上線的消息
pDoc->AlterUser(PACKAGE_USERADD, &userInfo, this);
}
void CDataSocket::OnReceiveLogout()
{
// 獲取登出用戶的信息
USER_INFO info;
if (Receive((void*)&info, sizeof(info), 0) != sizeof(info)) {
TRACE0("unable to receive user logout infomation.\n");
return;
}
/*
SOCKADDR_IN addrIn;
int addrLen = sizeof(SOCKADDR_IN);
if (!GetPeerName((SOCKADDR*)&addrIn, &addrLen)) {
TRACE0("Unable to get peer name.\n");
return;
}
*/
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CServerDoc* pDoc = (CServerDoc*)pFrame->GetActiveDocument();
CServerView* pView = (CServerView*)pFrame->GetActiveView();
/*
USER_INFO* pUserInfo = pDoc->LookupInfo(addrIn.sin_addr.s_addr, addrIn.sin_port);
if (pUserInfo == NULL) {
return;
}
*/
// 發(fā)送確認用戶退出的數(shù)據(jù)報
const WORD type = PACKAGE_LOGOUT;
if (Send((void*)&type, sizeof(type), 0) != sizeof(type)) {
TRACE0("failed to send confirm message to the quitting user.\n");
return;
}
// 關(guān)閉該套接字
pDoc->GetListenSocket()->CloseDataSocket(this);
// 向其他在線用戶發(fā)消息, 告知有一用戶離開
pDoc->AlterUser(PACKAGE_USERDEL, &info, this);
// 將該DataSocket加到死了的Socket鏈表
// pDoc->AddDeadSock(this);
// 更新顯示
CString strMsg;
strMsg.Format(IDS_LOGOUT, info.name,
inet_ntoa(*(in_addr*)&info.addr),
ntohs(info.port));
pView->AppendMessage(strMsg);
}
void CDataSocket::OnReceiveMessage()
{
char* pBuf = new char[0x1000];
ASSERT(pBuf != NULL);
if (Receive((void*)pBuf, 0x1000, 0) <= 0) {
TRACE0("failed to receive client message.");
return;
}
// 顯示消息
SOCKADDR_IN addrIn;
int addrLen = sizeof(SOCKADDR_IN);
if (!GetPeerName((SOCKADDR*)&addrIn, &addrLen)) {
TRACE0("Unable to get peer name.\n");
return;
}
CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
CServerDoc* pDoc = (CServerDoc*)pFrame->GetActiveDocument();
CServerView* pView = (CServerView*)pFrame->GetActiveView();
USER_INFO* pInfo = pDoc->LookupInfo(addrIn.sin_addr.s_addr, addrIn.sin_port);
CString strMsg;
strMsg.Format(IDS_MESSAGE, pInfo->name,
pBuf, inet_ntoa(*(in_addr*)&pInfo->addr));
pView->AppendMessage(strMsg);
}
void CDataSocket::OnClose(int nErrorCode)
{
// CAsyncSocket::OnClose(nErrorCode);
Close();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -