444 lines
11 KiB
C++
444 lines
11 KiB
C++
#include "stdafx.h"
|
|
#include "StockServer.h"
|
|
|
|
#include "ServerSocket.h"
|
|
#include "ClientSocket.h"
|
|
#include "..\\Common\\ComData.h"
|
|
|
|
#include "MainFrm.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CServerSocket
|
|
|
|
CServerSocket::CServerSocket(CMainFrame* pMainFrame)
|
|
{
|
|
ASSERT(pMainFrame);
|
|
m_pMainFrame = pMainFrame;
|
|
m_nMaxClients = -1;
|
|
}
|
|
|
|
CServerSocket::~CServerSocket()
|
|
{
|
|
CloseClients();
|
|
UpdateClientsList();
|
|
Close();
|
|
}
|
|
|
|
|
|
// Do not edit the following lines, which are needed by ClassWizard.
|
|
#if 0
|
|
BEGIN_MESSAGE_MAP(CServerSocket, CSocket)
|
|
//{{AFX_MSG_MAP(CServerSocket)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
#endif // 0
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CListeningSocket member functions
|
|
|
|
CPtrList* CServerSocket::GetClientsList()
|
|
{
|
|
if (m_ClientstList.IsEmpty())
|
|
return NULL;
|
|
|
|
return &m_ClientstList;
|
|
}
|
|
|
|
int CServerSocket::GetClientsConnectedCount()
|
|
{
|
|
return m_ClientstList.GetCount();
|
|
}
|
|
|
|
int CServerSocket::GetTotalMessagesCount()
|
|
{
|
|
int nMessageCount = 0;
|
|
int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
|
|
nMessageCount += pClientCom->szMessagesList.GetCount();
|
|
}
|
|
|
|
return nMessageCount;
|
|
}
|
|
|
|
|
|
|
|
BOOL CServerSocket::BeginListening(UINT uPort, int nMaxClients)
|
|
{
|
|
m_nMaxClients = nMaxClients;
|
|
|
|
if(!m_ClientstList.IsEmpty())
|
|
CloseClients();
|
|
|
|
if (!Create(uPort))
|
|
return FALSE;
|
|
|
|
if (!Listen())
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CServerSocket::OnAccept(int nErrorCode)
|
|
{
|
|
CSocket::OnAccept(nErrorCode);
|
|
|
|
ProcessAccept();
|
|
}
|
|
|
|
//when got a connection message from a client
|
|
void CServerSocket::ProcessAccept()
|
|
{
|
|
CClientSocket* pClientSocket = new CClientSocket(this);
|
|
ASSERT(pClientSocket);
|
|
|
|
if (!Accept(*pClientSocket)) {
|
|
delete pClientSocket;
|
|
return;
|
|
}
|
|
pClientSocket->Init();
|
|
|
|
if (m_nMaxClients != -1) {
|
|
if (m_nMaxClients <= m_ClientstList.GetCount()) {
|
|
try {
|
|
//send the connection confirmation to the client,add to the list - yh
|
|
CComData ComData;
|
|
ComData.m_ComDataType = CComData::COM_CLOSE;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
ComData.m_StringBody = "서버의 최대접속수를 넘었습니다.";
|
|
pClientSocket->SendCom(&ComData);
|
|
delete pClientSocket;
|
|
|
|
m_pMainFrame->AddMessage( ComData.m_FromID, ComData.m_StringBody );
|
|
return;
|
|
}
|
|
catch(CFileException* e){
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
}
|
|
}
|
|
|
|
try {
|
|
//send the connection confirmation to the client,add to the list - yh
|
|
CComData ComData;
|
|
ComData.m_ComDataType = CComData::COM_SIGN_IN;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
|
|
pClientSocket->SendCom(&ComData);
|
|
}
|
|
catch(CFileException* e){
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
|
|
CString szIPAddress;
|
|
UINT uPort;
|
|
pClientSocket->GetPeerName(szIPAddress, uPort);
|
|
|
|
sClientComInfos* pClientCom = new sClientComInfos;
|
|
ASSERT(pClientCom);
|
|
|
|
pClientCom->pSocket = (DWORD)pClientSocket;
|
|
pClientCom->strID = "";
|
|
pClientCom->szIPAddress = szIPAddress;
|
|
pClientCom->uPort = uPort;
|
|
pClientCom->TimeStarted = CTime::GetCurrentTime();
|
|
|
|
if(m_ClientstList.IsEmpty()){
|
|
m_ClientstList.AddHead(pClientCom);
|
|
}
|
|
else{
|
|
m_ClientstList.AddTail(pClientCom);
|
|
}
|
|
}
|
|
|
|
|
|
void CServerSocket::ProcessClientCom(CClientSocket* pClientSocket)
|
|
{
|
|
ASSERT(pClientSocket);
|
|
|
|
try {
|
|
|
|
CComData ComData;
|
|
pClientSocket->ReceiveCom(&ComData);
|
|
|
|
if(ComData.m_ComDataType == CComData::COM_SIGN_IN) {
|
|
|
|
if(IsThisLoginBeingUsed(pClientSocket, &ComData)) {
|
|
try {
|
|
//send the connection confirmation to the client,add to the list - yh
|
|
ComData.Initialize();
|
|
ComData.m_ComDataType = CComData::COM_CLOSE;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
ComData.m_StringBody = "접속제한 수를 넘었습니다.";
|
|
pClientSocket->SendCom(&ComData);
|
|
}
|
|
catch(CFileException* e) {
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
|
|
RemoveClient(pClientSocket);
|
|
return;
|
|
}
|
|
|
|
SendSignChange( pClientSocket, ComData.m_StringBody );
|
|
|
|
UpdateClientsList();
|
|
|
|
m_pMainFrame->AddMessage(ComData.m_StringBody, "Client Sign in." );
|
|
}
|
|
else if(ComData.m_ComDataType == CComData::COM_SIGN_OUT) {
|
|
RemoveClient(pClientSocket);
|
|
UpdateClientsList();
|
|
m_pMainFrame->AddMessage(ComData.m_FromID, "Client Sign out." );
|
|
}
|
|
else if(ComData.m_ComDataType == CComData::COM_MESSAGE) {
|
|
|
|
m_pMainFrame->AddMessage(ComData.m_FromID, ComData.m_StringBody );
|
|
UpdateClientsInfo(&ComData, pClientSocket);
|
|
}
|
|
}
|
|
catch(CFileException* e) {
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
}
|
|
|
|
void CServerSocket::SendSignChange(CClientSocket* pClientSocket, CString strNewId)
|
|
{
|
|
int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pClientCom->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
if(pClientSocket == pClientSocketTmp)
|
|
{
|
|
pClientCom->strID = strNewId; // 서버에서 클라이언트 리스트의 접속ID확정함.
|
|
|
|
CComData ComData;
|
|
ComData.m_ComDataType = CComData::COM_SIGN_CHANGE;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
ComData.m_StringBody = strNewId;
|
|
|
|
pClientSocket->SendCom(&ComData);
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CServerSocket::CheckAlive(CClientSocket* pClientSocket, int nCheck)
|
|
{
|
|
CComData ComData;
|
|
ComData.m_ComDataType = CComData::COM_CHECKALIVE;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
|
|
while( nCheck-- )
|
|
{
|
|
if( pClientSocket->SendCom(&ComData) == FALSE )
|
|
{
|
|
RemoveClient(pClientSocket);
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CServerSocket::IsThisLoginBeingUsed(CClientSocket* pClientSocket, CComData* pComData)
|
|
{
|
|
ASSERT(pClientSocket);
|
|
|
|
CString strCheckID = pComData->m_FromID;
|
|
|
|
if(strCheckID == CString((LPCTSTR)IDS_COM_SERVER))
|
|
return TRUE; // this name is used by server only!
|
|
|
|
if(m_ClientstList.IsEmpty()) return TRUE;
|
|
|
|
int nCount = m_ClientstList.GetCount();
|
|
int nCheckCount = 0;
|
|
while(nCheckCount++ < 2) { // 같은ID일경우 2개까지만 허용함.
|
|
|
|
BOOL bStop = TRUE;
|
|
|
|
for (int i = 0; i < nCount; i++) {
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pClientCom->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
if(strCheckID == pClientCom->strID &&
|
|
pClientSocket != pClientSocketTmp)
|
|
{
|
|
if( !CheckAlive(pClientSocketTmp) )
|
|
{
|
|
pComData->m_StringBody = strCheckID;
|
|
return FALSE;
|
|
}
|
|
|
|
strCheckID.Format("%s(%dth)", pComData->m_FromID, nCheckCount);
|
|
bStop = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( bStop ) {
|
|
pComData->m_StringBody = strCheckID;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CServerSocket::UpdateClientsList()
|
|
{
|
|
m_pMainFrame->UpdateClientsList(&m_ClientstList);
|
|
}
|
|
|
|
void CServerSocket::UpdateClientsInfo(CComData* pComData, CClientSocket* pClientSocket)
|
|
{
|
|
ASSERT(pComData);
|
|
|
|
int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pClientCom->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
if (pClientSocket == pClientSocketTmp) {
|
|
|
|
CString szBuf;
|
|
szBuf.Format("%s;%s", GlobalHelper::GetLocalTime(), pComData->m_StringBody);
|
|
if (pClientCom->szMessagesList.IsEmpty())
|
|
pClientCom->szMessagesList.AddHead(szBuf);
|
|
else
|
|
pClientCom->szMessagesList.AddTail(szBuf);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CServerSocket::RemoveClient(CClientSocket* pClientSocket)
|
|
{
|
|
ASSERT(pClientSocket);
|
|
|
|
int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pClientCom->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
if(pClientSocket == pClientSocketTmp) {
|
|
|
|
m_ClientstList.RemoveAt(m_ClientstList.FindIndex(i));
|
|
|
|
pClientSocketTmp->Close();
|
|
delete pClientSocketTmp;
|
|
pClientSocketTmp = NULL;
|
|
|
|
pClientCom->szMessagesList.RemoveAll();
|
|
delete pClientCom;
|
|
pClientCom = NULL;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CServerSocket::CloseClients()
|
|
{
|
|
int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pClientCom->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
try {
|
|
//send the connection confirmation to the client,add to the list - yh
|
|
CComData ComData;
|
|
ComData.m_ComDataType = CComData::COM_CLOSE;
|
|
ComData.m_FromID = CString((LPCTSTR)IDS_COM_SERVER);
|
|
ComData.m_StringBody = "연결종료합니다.";
|
|
|
|
pClientSocketTmp->SendCom(&ComData);
|
|
}
|
|
catch(CFileException* e) {
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
|
|
pClientSocketTmp->Close();
|
|
delete pClientSocketTmp;
|
|
pClientSocketTmp = NULL;
|
|
|
|
m_pMainFrame->AddMessage(pClientCom->strID, "연결종료합니다.");
|
|
|
|
pClientCom->szMessagesList.RemoveAll();
|
|
delete pClientCom;
|
|
pClientCom = NULL;
|
|
}
|
|
|
|
m_ClientstList.RemoveAll();
|
|
}
|
|
|
|
void CServerSocket::SendMessageTo(CString szClient, CString szMessage)
|
|
{
|
|
/* int nCount = m_ClientstList.GetCount();
|
|
for (int i = 0; i < nCount; i++) {
|
|
|
|
sClientComInfos* pClientCom = (sClientComInfos*)m_ClientstList.GetAt(m_ClientstList.FindIndex(i));
|
|
ASSERT(pClientCom);
|
|
CComData* pComDataTmp = (CComData*)&pClientCom->ComData;
|
|
ASSERT(pComDataTmp);
|
|
CClientSocket* pClientSocketTmp = (CClientSocket*)pComDataTmp->pSocket;
|
|
ASSERT(pClientSocketTmp);
|
|
|
|
if (pComDataTmp->szFrom == szClient) {
|
|
|
|
try {
|
|
//send the connection confirmation to the client,add to the list - yh
|
|
CComData ComDataTmp;
|
|
ComDataTmp.szFrom = CString((LPCTSTR)IDS_COM_SERVER);
|
|
ComDataTmp.uSignIcon = SERVER_ICON;
|
|
ComDataTmp.szMessage = szMessage;
|
|
ComDataTmp.uMessage = CComData::COM_PRIVATE_MESSAGE;
|
|
pClientSocketTmp->SendCom(&ComDataTmp);
|
|
}
|
|
catch(CFileException* e) {
|
|
TCHAR csError[CHAR_BUFFER_SIZE];
|
|
e->GetErrorMessage(csError, CHAR_BUFFER_SIZE);
|
|
AfxMessageBox(csError);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
|