📄 serverdoc.cpp
字号:
// ServerDoc.cpp : implementation file
//
#include "stdafx.h"
#include "miniSQL.h"
#include "ServerDoc.h"
#include "ServerView.h"
#include "ConnectDlg.h"
#include "User.h"
#include "table.h"
#include "SockExec.h"
#include "Error.h"
#include "AdrDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CMiniSQLApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CServerDoc
IMPLEMENT_DYNCREATE(CServerDoc, CDocument)
CServerDoc::CServerDoc()
{
m_pSocket = NULL;
}
BOOL CServerDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
CConnectDlg dlg;
if( dlg.DoModal() == IDOK )
{
m_pSocket = new CListeningSocket( this );
if( m_pSocket->Create( dlg.m_port + 700, SOCK_STREAM, dlg.m_address ) )
{
if( m_pSocket->Listen() )
{
Message( "Successful creating ServeR!" );
return TRUE;
}
}
else
{
if( AfxMessageBox( "创建SOCKET失败,要重试吗?", MB_ICONQUESTION | MB_YESNO ) == IDYES )
return OnNewDocument();
}
}
::Message( "Error creating socket or user aborted!\n" );
return FALSE;
}
CServerDoc::~CServerDoc()
{
if( m_pSocket )
delete m_pSocket;
theApp.m_bConnection = FALSE;
}
BEGIN_MESSAGE_MAP(CServerDoc, CDocument)
//{{AFX_MSG_MAP(CServerDoc)
ON_COMMAND(ID_ADDRESS, OnAddress)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDoc diagnostics
#ifdef _DEBUG
void CServerDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CServerDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CServerDoc serialization
void CServerDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
}
}
/////////////////////////////////////////////////////////////////////////////
// CServerDoc commands
BOOL CServerDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
return CDocument::OnSaveDocument( lpszPathName );
}
void CServerDoc::DeleteContents()
{
delete m_pSocket;
m_pSocket = NULL;
while( !m_connectionList.IsEmpty() )
{
CClientSocket* pSocket = ( CClientSocket* )m_connectionList.RemoveHead();
CMsg msg( SERVER_CLOSE );
msg.m_bClose = TRUE;
SendMsg( pSocket, msg );
if( !pSocket->IsAborted() )
{
pSocket->ShutDown();
BYTE buffer[ 50 ];
while( pSocket->Receive( buffer, 50 ) > 0 );
delete pSocket;
}
}
CDocument::DeleteContents();
}
BOOL CServerDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
return TRUE;
}
void CServerDoc::ProcessPendingAccept()
{
CClientSocket* pSocket = new CClientSocket( this );
if( m_pSocket->Accept( *pSocket ) )
{
pSocket->Init();
m_connectionList.AddTail( pSocket );
}
else
delete pSocket;
}
void CServerDoc::ProcessPendingRead(CClientSocket *pSocket)
{
do
{
CMsg* pMsg = ReadMsg( pSocket );
if( pMsg->m_bClose )
{
if( pSocket->m_name.GetLength() )
{
CString text( pMsg->m_msgList.GetHead() );
CString address, strPort;
UINT port;
pSocket->GetPeerName( address, port );
strPort.Format( "%d", port );
text += (CString)" (from " + address + ":" + strPort +
") has disconnected from the server.";
Message( text );
}
CloseSocket( pSocket );
break;
}
switch( pMsg->m_cmdID )
{
case LOGON:
{
CString name, code;
name = pMsg->m_msgList.RemoveHead();
code = pMsg->m_msgList.RemoveHead();
CMsg msg( LOGON );
if( msg.m_nCount = (int)UserLogon( name, code ) )
{
pSocket->m_name = name;
pSocket->m_type = (DWORD)msg.m_nCount;
CString text = name;
CString address, strPort;
UINT port;
pSocket->GetPeerName( address, port );
strPort.Format( "%d", port );
text += (CString)" (from " + address + ":" + strPort +
") has connected to the server.";
Message( text );
SendMsg( pSocket, msg );
msg.Init();
msg.m_cmdID = FILEBAR_INIT;
PreScanFile( msg );
SendMsg( pSocket, msg );
}
else
SendMsg( pSocket, msg );
}
break;
case FILEBAR_EXPAND:
{
CString tname = pMsg->m_msgList.GetHead();
CMsg msg( FILEBAR_EXPAND );
ScanFile( tname, msg );
SendMsg( pSocket, msg );
}
break;
case COMMAND:
{
CSockExec* pExec = new CSockExec( pMsg->m_msgList.GetHead(), pSocket, this );
try
{
pExec->Exec();
}
catch( Error& e )
{
CString text( "ERRORS OCCOR, PROCESS ABORTED : \r\n\t" );
text += e.GetErrStr();
Message( text );
CMsg msg( FAILED );
msg.m_nCount = pExec->LineNo() - 1;
msg.m_msgList.AddTail( e.GetErrStr() );
CString str;
str.Format( "%d", e.m_ErrType );
msg.m_msgList.AddTail( str + "\n" );
SendMsg( pSocket, msg );
delete pExec;
}
}
break;
case STEP_COMMAND:
{
CSockExec* pExec = new CSockExec( pMsg->m_msgList.GetHead(), pSocket, this );
try
{
pExec->SingleExec();
}
catch( Error& e )
{
CString text( "ERRORS OCCOR, PROCESS ABORTED : \r\n\t" );
text += e.GetErrStr();
Message( text );
CMsg msg( FAILED );
msg.m_nCount = pExec->LineNo() - 1;
msg.m_msgList.AddTail( e.GetErrStr() );
CString str;
str.Format( "%d", e.m_ErrType );
msg.m_msgList.AddTail( str );
SendMsg( pSocket, msg );
delete pExec;
}
}
break;
default:
;
}
}
while( !pSocket->m_pArchiveIn->IsBufferEmpty() );
}
CMsg* CServerDoc::ReadMsg(CClientSocket *pSocket)
{
static CMsg msg;
TRY
{
pSocket->ReceiveMsg( msg );
}
CATCH(CFileException, e)
{
Message( "Error reading socket!" );
msg.m_bClose = TRUE;
pSocket->Abort();
}
END_CATCH
return &msg;
}
void CServerDoc::SendMsg(CClientSocket *pSocket, CMsg &msg)
{
TRY
{
pSocket->SendMsg( msg );
}
CATCH( CFileException, e )
{
pSocket->Abort();
Message( "Error sending message!" );
}
END_CATCH
}
void CServerDoc::Message(LPCTSTR lpszMessage)
{
( (CServerView*)m_viewList.GetHead() )->Message( lpszMessage );
}
void CServerDoc::CloseSocket(CClientSocket *pSocket)
{
pSocket->Close();
POSITION pos, temp;
for( pos = m_connectionList.GetHeadPosition(); pos; )
{
temp = pos;
CClientSocket* pSock = ( CClientSocket* )m_connectionList.GetNext( pos );
if( pSock == pSocket )
{
m_connectionList.RemoveAt( temp );
break;
}
}
delete pSocket;
}
DWORD CServerDoc::UserLogon(CString& name, CString& code)
{
if( name == _T("admin") && code == _T("admin") )
return LOG_ADMIN;
else if( name == _T("superuser") && code == _T("superuser") )
return LOG_SUPERUSER;
else if( name == _T("user") && code == _T("user") )
return LOG_USER;
else
{
CFileStatus status;
CString path( theApp.dir );
path += "\\user.dat";
if( CFile::GetStatus( path, status ) )
{
CFile File( path, CFile::modeRead );
CArchive ar( &File, CArchive::load );
int length = 0;
ar>>length;
for( int i = 0; i < length; i++ )
{
CUser user;
user.Serialize( ar );
if( name == user.m_user && code == user.m_code )
return user.m_type;
}
return 0;
}
else
{
CFile File( path, CFile::modeCreate | CFile::modeWrite );
CArchive ar( &File, CArchive::store );
int length = 0;
ar<<length<<'\0';
return 0;
}
}
}
void CServerDoc::PreScanFile( CMsg& msg )
{
WIN32_FIND_DATA FileData;
HANDLE hFind;
hFind = ::FindFirstFile( ".\\*.msl", &FileData);
if( hFind != INVALID_HANDLE_VALUE ){
CString fname = FileData.cFileName;
int len = fname.GetLength();
msg.m_msgList.AddTail( fname.Left( len - 4 ) );
while( ::FindNextFile(hFind, &FileData) ){
fname = FileData.cFileName;
len = fname.GetLength();
msg.m_msgList.AddTail( fname.Left( len - 4 ) );
}
}
}
void CServerDoc::ScanFile( CString& tname, CMsg& msg )
{
CTable table( (LPCTSTR) tname );
msg.m_nCount = table.attr.attr.num;
for( int i = 0; i < table.attr.attr.num; i++ )
{
CString str;
str = table.attr.attr.attr[i].name;
str += ":";
switch( table.attr.attr.attr[i].type.id )
{
case _INT: str += "int"; break;
case _LONG: str += "long"; break;
case _FLOAT: str += "float"; break;
case _DATE: str += "date"; break;
case _STRING:
CString temp;
temp.Format( "char[%d]", table.attr.attr.attr[i].type.size - 2 );
str += temp;
break;
}
msg.m_msgList.AddTail( str );
}
for( i = 0; i < table.attr.index_num; i++ )
{
CString str( _T("index:") );
str += table.attr.index_table[i];
msg.m_msgList.AddTail( str );
}
}
void CServerDoc::ShowAddress()
{
CAdrDlg dlg;
CString address, strPort;
UINT port;
m_pSocket->GetSockName( address, port );
strPort.Format( "%d", port );
address += " : " + strPort;
dlg.m_address = address;
dlg.DoModal();
}
void CServerDoc::OnAddress()
{
ShowAddress();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -