I'm currently creating a non-blocking server class that using winsock2, but I'm having some problems. I've read an article and used code from a mud as a reference. Maybe I don't know enough about it yet, but I just can't seem to figure out what's wrong. The code isn't commented much at all, but I hope someone can figure it out. Here it is.
NonBlockingServer.h
#include "GlobalDefs.h"
#include "GameWorld.h"
#include <winsock2.h>
class CClient
{
public:
CClient();
CCharacter *m_pChar;
sockaddr_in m_sinClient;
int m_nSinSize;
SOCKET m_sockClient;
char *m_byteRecvData;
char *m_byteSendData[10];
int m_nSendDataSize[10];
CClient *m_pNextClient;
CClient *m_pPrevClient;
void Send(char *byteData);
void Send(char *byteData, int nDataSize);
};
class CNonBlockingServer
{
public:
CNonBlockingServer(unsigned int nPort = 4000, unsigned int nMaxClients = 1);
~CNonBlockingServer();
//private:
WSADATA m_wsData; //winsock init data
sockaddr_in m_sinServer; //server socket info
int m_nSinSize; //size of server socket info
SOCKET m_sockServer; //handle to socket
unsigned int m_nMaxClients;
fd_set m_fdRecv,
m_fdSend,
m_fdError; //sets of sockets to gather info from
public:
CClient *m_cClients;
unsigned int m_nNumClients;
int m_nNumSocksRdy;
void PollSockets();
void ReceiveData();
void SendData();
void GetData(CClient *pClient, char *szReturn) //must be changed for non-text data
{
strcpy(szReturn, pClient->m_byteRecvData);
*pClient->m_byteRecvData = '\0';
}
void DisconnectClient(CClient *pClient);
};
NonBlockingServer.cpp
#include "StdAfx.h"
#include "NonBlockingServer.h"
CClient::CClient()
{
m_byteRecvData = new char[g_nMaxBufLen];
for(int i = 0; i < 10; i++) m_byteSendData = new char[g_nMaxBufLen];
*m_byteRecvData = '\0';
}
void CClient::Send(char *byteData)
{
for(int i = 0; i < 10; i++)
{
if(!m_nSendDataSize)
{
strcpy(m_byteSendData, byteData);
m_nSendDataSize = strlen(m_byteSendData);
}
}
}
void CClient::Send(char *byteData, int nDataSize)
{
for(int i = 0; i < 10; i++)
{
if(!m_nSendDataSize && nDataSize <= g_nMaxBufLen)
{
memcpy(m_byteSendData, byteData, nDataSize);
m_nSendDataSize = nDataSize;
}
}
}
CNonBlockingServer::CNonBlockingServer(unsigned int nPort, unsigned int nMaxClients)
: m_nMaxClients(nMaxClients)
{
WSAStartup(0x0202, &m_wsData);
m_sinServer.sin_family = AF_INET;
m_sinServer.sin_port = htons(nPort);
m_sinServer.sin_addr.s_addr = htonl(INADDR_ANY);
m_nSinSize = sizeof(sockaddr_in);
m_sockServer = socket(AF_INET, SOCK_STREAM, 0);
bind(m_sockServer, (sockaddr *)&m_sinServer, sizeof(sockaddr));
listen(m_sockServer, m_nMaxClients);
m_nNumClients = 0;
}
CNonBlockingServer::~CNonBlockingServer()
{
CClient *pClient = m_cClients->m_pPrevClient;
while(pClient != m_cClients)
{
closesocket(pClient->m_sockClient);
pClient = pClient->m_pPrevClient;
delete pClient->m_pNextClient;
pClient->m_pNextClient = NULL;
}
if(m_cClients)
{
closesocket(m_cClients->m_sockClient);
delete m_cClients;
}
}
void CNonBlockingServer:<img src="tongue.gif" width=15 height=15 align=middle>ollSockets()
{
CClient *pClient = m_cClients;
const timeval tvTimeout = { 0, 0 };
int nMaxDesc = m_sockServer;
FD_ZERO(&m_fdRecv);
FD_ZERO(&m_fdSend);
FD_ZERO(&m_fdError);
FD_SET(m_sockServer, &m_fdRecv);
for(unsigned int i = 0; i < m_nNumClients; i++)
{
nMaxDesc = (nMaxDesc > pClient->m_sockClient) ? nMaxDesc : pClient->m_sockClient;
FD_SET(pClient->m_sockClient, &m_fdRecv);
FD_SET(pClient->m_sockClient, &m_fdSend);
FD_SET(pClient->m_sockClient, &m_fdError);
pClient = pClient->m_pNextClient;
}
pClient = m_cClients;
m_nNumSocksRdy = select(nMaxDesc, &m_fdRecv, &m_fdSend, &m_fdError, &tvTimeout);
if(m_nNumSocksRdy == SOCKET_ERROR)
{
int nError = WSAGetLastError();
char szError[5];
sprintf(szError, "%d\n", nError);
printf(szError);
return;
}
if(FD_ISSET(m_sockServer, &m_fdRecv))
{
CClient *pNewClient = new CClient;
if(m_nNumClients == 0)
m_cClients = pNewClient;
else if(m_nNumClients == 1)
{
pNewClient->m_pPrevClient = m_cClients;
pNewClient->m_pNextClient = m_cClients;
m_cClients->m_pNextClient = pNewClient;
m_cClients->m_pPrevClient = pNewClient;
}
else
{
pNewClient->m_pPrevClient = m_cClients->m_pPrevClient;
pNewClient->m_pNextClient = m_cClients;
m_cClients->m_pPrevClient->m_pNextClient = pNewClient;
m_cClients->m_pPrevClient = pNewClient;
}
pNewClient->m_sockClient = accept(m_sockServer, (sockaddr *)&pNewClient->m_sinClient, &pNewClient->m_nSinSize);
m_nNumClients++;
m_nNumSocksRdy–;
pNewClient->m_pChar = new CCharacter; //special logon code
pNewClient->m_pChar->m_nLogonSeq = 1; //for the mud
}
for(i = 0; i < m_nNumSocksRdy<img src="wink.gif" width=15 height=15 align=middle>
{
if(FD_ISSET(pClient->m_sockClient, &m_fdError))
{
DisconnectClient(pClient);
m_nNumSocksRdy–;
}
pClient = pClient->m_pNextClient;
}
}
void CNonBlockingServer::ReceiveData()
{
if(!m_nNumClients) return;
CClient *pClient = m_cClients;
for(unsigned int i = 0; i < m_nNumClients; i++)
{
if(FD_ISSET(pClient->m_sockClient, &m_fdRecv))
{
recv(pClient->m_sockClient, pClient->m_byteRecvData, g_nMaxBufLen, 0);
m_nNumSocksRdy–;
}
pClient = pClient->m_pNextClient;
if(!m_nNumSocksRdy && pClient == m_cClients || m_nNumClients == 1) return;
}
}
void CNonBlockingServer::SendData()
{
if(!m_nNumClients) return;
CClient *pClient = m_cClients;
for(unsigned int i = 0; i < m_nNumClients; i++)
{
if(FD_ISSET(pClient->m_sockClient, &m_fdSend))
{
if(pClient->m_nSendDataSize > 0)
{
send(pClient->m_sockClient, pClient->m_byteSendData[0], pClient->m_nSendDataSize[0], 0);
for(int i = 0; i < 10; i++)
{
pClient->m_byteSendData = pClient->m_byteSendData[i+1];
pClient->m_nSendDataSize = pClient->m_nSendDataSize[i+1];
}
m_nNumSocksRdy–;
}
pClient = pClient->m_pNextClient;
if(!m_nNumSocksRdy && pClient == m_cClients || m_nNumClients == 1) return;
}
}
}
void CNonBlockingServer::DisconnectClient(CClient *pClient)
{
delete pClient->m_pChar;
closesocket(pClient->m_sockClient);
m_nNumClients–;
delete[] pClient->m_byteRecvData;
for(int i = 0; i < 10; i++) delete[] pClient->m_byteSendData;
pClient->m_pNextClient->m_pPrevClient = pClient->m_pPrevClient;
pClient->m_pPrevClient->m_pNextClient = pClient->m_pNextClient;
delete pClient;
}
</pre>
<SPAN CLASS=editedby>[edited by - SyntheticHate on March 5, 2003 9:09:59 PM]</SPAN> </i>