📄 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();
// 设定套接字选项
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;
}
// 查看数据包类型
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;
}
// 你可以在这里检测用户名和密码的正确性, 为简单起见, 我们在这里跳过
// 向其他用户发送该用户上线的消息
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);
// 向登录用户发送在线人员列表
pDoc->SendUserListTo(userInfo, this);
// 向所有用户发送该用户上线的消息
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;
}
*/
// 发送确认用户退出的数据报
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;
}
// 关闭该套接字
pDoc->GetListenSocket()->CloseDataSocket(this);
// 向其他在线用户发消息, 告知有一用户离开
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 + -