📄 zfxws.cpp
字号:
return ZFX_FAIL;
}
// initialize all client slots as invalid
for (int i=0; i<256; i++) {
m_Clients[i].skToClient = INVALID_SOCKET;
m_Clients[i].nID = 0;
}
return ZFX_OK;
} // CreateServer
/*----------------------------------------------------------------*/
/**
* Send a data package from the server to all connected clients.
* We need to loop through all active connections and send it.
*/
HRESULT ZFXWS::SendToClients(const ZFXPACKAGE *pPkg) {
HRESULT hr=ZFX_OK;
int nBytes=0;
int nSize=g_PkgSize+pPkg->nLength;
// security checks
if (m_Mode != NMD_SERVER) return ZFX_FAIL;
if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;
// serialize data in order to send from one mem segment
memcpy(m_Buffer, pPkg, g_PkgSize);
memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);
// now go send it actually
for (UINT i=0; i<m_ClCount; i++) {
if (m_Clients[i].skToClient != INVALID_SOCKET) {
nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
// if failed report but go on with next clients
if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
hr = ZFX_FAIL;
}
}
return hr;
} // SendToClients
/*----------------------------------------------------------------*/
/**
* Send a data package from the server to the given client. We
* need to loop through all active connections to find that one.
*/
HRESULT ZFXWS::SendToClient(const ZFXPACKAGE *pPkg, UINT nCID) {
HRESULT hr=ZFX_OK;
int nBytes=0;
int nSize=g_PkgSize+pPkg->nLength;
// security checks
if (m_Mode != NMD_SERVER) return ZFX_FAIL;
if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;
// serialize data in order to send from one mem segment
memcpy(m_Buffer, pPkg, g_PkgSize);
memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);
// now go send it actually
for (UINT i=0; i<m_ClCount; i++) {
if ( (m_Clients[i].skToClient != INVALID_SOCKET) &&
(m_Clients[i].nID == nCID) ) {
nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
// if failed report but go on with next clients
if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
hr = ZFX_FAIL;
}
}
return hr;
} // SendToClient
/*----------------------------------------------------------------*/
/**
* A client just sends the package over its socket that is
* connected to the one and only server. No problems here.
*/
HRESULT ZFXWS::SendToServer(const ZFXPACKAGE *pPkg) {
int nBytes=0;
int nSize=g_PkgSize+pPkg->nLength;
// security checks
if (nSize > m_nMaxSize) return ZFX_OUTOFMEMORY;
// serialize data in order to send from one mem segment
memcpy(m_Buffer, pPkg, g_PkgSize);
memcpy(m_Buffer+g_PkgSize, pPkg->pData, pPkg->nLength);
// if pkg was sent by server then
// feed it directly into its own queue
if (m_Mode == NMD_SERVER) {
m_pSockObj->FeedByHand( (ZFXPACKAGE*)m_Buffer );
return ZFX_OK;
}
// now go send it actually
nBytes = m_pSockObj->Send(m_Buffer, nSize);
if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) ) {
Log("error: SendToServer() failed");
return ZFX_FAIL;
}
return ZFX_OK;
} // SendToServer
/*----------------------------------------------------------------*/
/**
* Application must call this if a WM_ is coming from network.
*/
HRESULT ZFXWS::MsgProc(WPARAM wp, LPARAM lp) {
WORD wEvent, wError;
// get data
wError = HIWORD(lp);
wEvent = LOWORD(lp);
// which event
switch (wEvent) {
// confirmation after successful connection
case FD_CONNECT: break;
// client wants to be accepted
case FD_ACCEPT: { return OnAccept(); } break;
// we are receiving something
case FD_READ: { return OnReceive(wp); } break;
// a client wants to go offline
case FD_CLOSE: { return OnDisconnect(wp); } break;
// we sent something?
case FD_WRITE: break;
}
return ZFX_OK;
} // MsgProc
/*----------------------------------------------------------------*/
/**
* There is someone is the queue of our server waiting to be accepted
* so do him the favor.
*/
HRESULT ZFXWS::OnAccept(void) {
int nSize=0, nBytes=0, i=m_ClCount;
// maximum of 255 clients at all
if (m_ClCount >= 255) return ZFX_OUTOFMEMORY;
// application defined maximum number
if ( (m_ClMax > 0) &&
(m_ClCount >= m_ClMax) )
return ZFX_OUTOFMEMORY;
if (FAILED(m_pSockObj->Accept( &(m_Clients[i].skToClient) )))
return ZFX_FAIL;
// SEND ITS ID TO THE NEW CLIENT:
ZFXPACKAGE *pPkg = (ZFXPACKAGE*)m_Buffer;
pPkg->pData = &m_Buffer[g_PkgSize];
pPkg->nLength = sizeof(UINT);
pPkg->nType = 0; // ID Msg
pPkg->nSender = 0; // Server
memcpy(pPkg->pData, &m_ClID, sizeof(UINT));
// add counters
m_Clients[i].nID = m_ClID;
m_ClCount++;
m_ClID++;
nSize = g_PkgSize + pPkg->nLength;
nBytes = m_pSockObj->Send(m_Buffer, nSize, m_Clients[i].skToClient);
if ( (nBytes==SOCKET_ERROR) || (nBytes<nSize) )
return ZFX_FAIL;
// INFORM ALL CLIENTS AND THE SERVER ABOUT THE NEW KID IN TOWN
pPkg->nType = 1;
SendToClients(pPkg);
// feed msg into server msg-queue
m_pSockObj->FeedByHand(pPkg);
return ZFX_OK;
} // OnAccept
/*----------------------------------------------------------------*/
/**
* The giving socket has data to be received in its queue. Just do it!
*/
HRESULT ZFXWS::OnReceive(SOCKET skReceiving) {
if (m_bRunning) {
return m_pSockObj->Receive(skReceiving);
}
else {
Log("error: m_bRunning=0 in ZFXWS::OnReceive");
return ZFX_FAIL;
}
} // OnReceive
/*----------------------------------------------------------------*/
/**
* Close the given socket if he wants to disconnect.
*/
HRESULT ZFXWS::OnDisconnect(SOCKET skDisconnecting) {
UCHAR i=0;
if (skDisconnecting==INVALID_SOCKET)
return ZFX_FAIL;
if (m_Mode==NMD_SERVER) {
// delete from the list of active clients
for (i=0; i<m_ClCount; i++) {
if (m_Clients[i].skToClient == skDisconnecting)
break;
}
if (i>=m_ClCount) {
Log("error: not listed client wants to be disconnected");
return ZFX_FAIL;
}
// shutdown and close socket
if ( shutdown(m_Clients[i].skToClient,0x02)==SOCKET_ERROR )
m_pSockObj->LogLastWSAError("shutdown() in ZFXWS::OnDisconnect");
if ( closesocket(m_Clients[i].skToClient)==SOCKET_ERROR )
m_pSockObj->LogLastWSAError("closesocket() in ZFXWS::OnDisconnect");
m_Clients[i].skToClient = INVALID_SOCKET;
// inform clients and the server about disconnect
ZFXPACKAGE *pPkg = (ZFXPACKAGE*)m_Buffer;
pPkg->pData = &m_Buffer[g_PkgSize];
pPkg->nLength = sizeof(UINT);
pPkg->nType = 2; // ID Msg disconnecting
pPkg->nSender = 0; // Server
memcpy(pPkg->pData, &m_Clients[i].nID, sizeof(UINT));
SendToClients(pPkg);
// feed msg into server msg-queue
m_pSockObj->FeedByHand(pPkg);
// copy last struct to deleted field, adjust counter
memcpy(&m_Clients[i], &m_Clients[m_ClCount-1], sizeof(ZFXCLIENT));
m_ClCount--;
}
else {
if ( shutdown(m_pSockObj->GetSocket(),0x02)==SOCKET_ERROR )
m_pSockObj->LogLastWSAError("shutdown() in ZFXWS::OnDisconnect");
if ( closesocket(m_pSockObj->GetSocket())==SOCKET_ERROR )
m_pSockObj->LogLastWSAError("closesocket() in ZFXWS::OnDisconnect");
}
Log("one client disconnected");
return ZFX_OK;
} // OnDisconnect
/*----------------------------------------------------------------*/
/**
* write outputstring to attribut outputstream if exists
* -> IN: bool - flush immediately
* char - format string to output
* ... - output values
*/
void ZFXWS::Log(char *chString, ...) {
char ch[256];
char *pArgs;
pArgs = (char*) &chString + sizeof(chString);
vsprintf(ch, chString, pArgs);
fprintf(m_pLog, "[ZFXWSDevice]: ");
fprintf(m_pLog, ch);
fprintf(m_pLog, "\n");
if (g_bLF)
fflush(m_pLog);
} // Log
/*----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -