📄 serv.c
字号:
Serv_FreeClientList(&ServerInfo);
closesocket(hServerSocket);
}
/**********************************************************************
*
* Serv_ProcessSocketWait
*
* Process wait for socket communications
*
**********************************************************************/
BOOL Serv_ProcessSocketWait(PSERVER_INFO pServerInfo)
{
BOOL bProcessSocketInformation = FALSE;
BOOL bNoDataToProcess = TRUE;
struct timeval stTimeout;
PCLIENT_INFO pClientInfo;
int RetVal;
/*
* Loop Until Client Sends Data, Server is Terminated or Another Client Connects
*/
while(bNoDataToProcess)
{
FD_ZERO(&pServerInfo->stReadFDS);
FD_ZERO(&pServerInfo->stXcptFDS);
FD_SET(pServerInfo->hServerSocket, &pServerInfo->stReadFDS);
pServerInfo->DataSockets = 0;
pClientInfo = pServerInfo->pClientInfoList;
while(pClientInfo)
{
FD_SET(pClientInfo->hSocket, &pServerInfo->stReadFDS);
pClientInfo = pClientInfo->Next;
}
stTimeout.tv_sec = 1;
stTimeout.tv_usec = 0;
RetVal = select(0, &pServerInfo->stReadFDS, NULL, &pServerInfo->stXcptFDS, &stTimeout);
if(RetVal == 0 || RetVal == SOCKET_ERROR)
{
if(kbhit())
{
switch(getch())
{
case 'q' :
case 'Q' :
bNoDataToProcess = FALSE;
pServerInfo->bServerIsRunning = FALSE;
break;
}
}
}
else
{
bNoDataToProcess = FALSE;
bProcessSocketInformation = TRUE;
pServerInfo->DataSockets = RetVal;
}
}
return bProcessSocketInformation;
}
/**********************************************************************
*
* Serv_ProcessIncommingSockets
*
* Accept new client connections
*
**********************************************************************/
void Serv_ProcessIncommingSockets(PSERVER_INFO pServerInfo)
{
SOCKADDR_IN NewClientSockAddr = {0};
SOCKET hNewClient;
UINT uiLength;
PCLIENT_INFO pClientInfo, pClientInfoWalker;
/*
* Check if the Server Socket has any new connecting clients
*/
if(FD_ISSET(pServerInfo->hServerSocket, &pServerInfo->stReadFDS))
{
pServerInfo->DataSockets--;
uiLength = sizeof(SOCKADDR_IN);
if((hNewClient = accept(pServerInfo->hServerSocket, (struct sockaddr *)&NewClientSockAddr, &uiLength)) != INVALID_SOCKET)
{
/*
* Send All Client Information to the new Client
*/
Serv_SendNewClientBroadCast(hNewClient, pServerInfo);
pClientInfo = Serv_CreateNewClient(hNewClient, &NewClientSockAddr);
if(pClientInfo)
{
if(pServerInfo->pClientInfoList)
{
pClientInfoWalker = pServerInfo->pClientInfoList;
while(pClientInfoWalker->Next)
{
pClientInfoWalker = pClientInfoWalker->Next;
}
pClientInfoWalker->Next = pClientInfo;
}
else
{
pServerInfo->pClientInfoList = pClientInfo;
}
}
else
{
Serv_DisplayErrorMsg(SERV_MEMORY_ERROR);
closesocket(hNewClient);
}
}
}
}
/**********************************************************************
*
* Serv_CreateNewClient
*
* Create a new client data structure
*
**********************************************************************/
PCLIENT_INFO Serv_CreateNewClient(SOCKET hNewClientSocket, SOCKADDR_IN *pNewClientSockAddr)
{
PCLIENT_INFO pClientInfo;
pClientInfo = (PCLIENT_INFO)LocalAlloc(LMEM_ZEROINIT, sizeof(CLIENT_INFO));
if(pClientInfo)
{
pClientInfo->hSocket = hNewClientSocket;
pClientInfo->SockAddr = *pNewClientSockAddr;
printf("Connected IP = %i.%i.%i.%i\n", pClientInfo->SockAddr.sin_addr.s_addr&0xFF,
pClientInfo->SockAddr.sin_addr.s_addr>>8 & 0xFF,
pClientInfo->SockAddr.sin_addr.s_addr>>16 & 0xFF,
pClientInfo->SockAddr.sin_addr.s_addr>>24 & 0xFF);
}
return pClientInfo;
}
/**********************************************************************
*
* Serv_ProcessChatBroadcast
*
* Broadcast Client Chat Messages
*
**********************************************************************/
void Serv_ProcessChatBroadcast(PSERVER_INFO pServerInfo)
{
PCLIENT_INFO pClientInfo, pClientPrev = NULL;
int RetVal;
char szBuffer[1000];
pClientInfo = pServerInfo->pClientInfoList;
while(pServerInfo->DataSockets && pClientInfo)
{
if(FD_ISSET(pClientInfo->hSocket, &pServerInfo->stReadFDS))
{
pServerInfo->DataSockets--;
/*
* Get Incomming Data
*/
RetVal = recv(pClientInfo->hSocket, szBuffer, sizeof(szBuffer), 0);
/*
* Client Error?
*/
if(RetVal == 0 || RetVal == SOCKET_ERROR)
{
/*
* If Client has a NickName, Broadcast he left the channel.
*/
if(pClientInfo->bSetNick)
{
sprintf(szBuffer, "***** %s Has Left the chat line\n", pClientInfo->Nick);
Serv_SendClientBroadCast(pClientInfo, pServerInfo, szBuffer);
}
/*
* Close Socket, remove client from linked list and free the memory.
*/
closesocket(pClientInfo->hSocket);
if(pClientPrev)
{
pClientPrev->Next = pClientInfo->Next;
LocalFree(pClientInfo);
pClientInfo = pClientPrev->Next;
}
else
{
pServerInfo->pClientInfoList = pClientInfo->Next;
LocalFree(pClientInfo);
pClientInfo = pServerInfo->pClientInfoList;
}
}
else
{
szBuffer[RetVal] = 0;
/*
* The First Packet from a client is it's nick name.
*/
if(!pClientInfo->bSetNick)
{
strcpy(pClientInfo->Nick, szBuffer);
sprintf(szBuffer, "*** %s has joined the chat line\n", pClientInfo->Nick);
pClientInfo->bSetNick = TRUE;
}
Serv_SendClientBroadCast(pClientInfo, pServerInfo, szBuffer);
pClientPrev = pClientInfo;
pClientInfo = pClientInfo->Next;
}
}
else
{
pClientPrev = pClientInfo;
pClientInfo = pClientInfo->Next;
}
}
}
/**********************************************************************
*
* Serv_FreeClientList
*
* Free All Clients
*
**********************************************************************/
void Serv_FreeClientList(PSERVER_INFO pServerInfo)
{
PCLIENT_INFO pClientInfo = pServerInfo->pClientInfoList, pNextClient;
while(pClientInfo)
{
pNextClient = pClientInfo->Next;
closesocket(pClientInfo->hSocket);
LocalFree(pClientInfo);
pClientInfo = pNextClient;
}
pServerInfo->pClientInfoList = NULL;
}
/**********************************************************************
*
* Serv_SendClientBroadCast
*
* Send All Connected Client Information to All but one Client
*
**********************************************************************/
void Serv_SendClientBroadCast(PCLIENT_INFO pClientInfo, PSERVER_INFO pServerInfo, char *pszBuffer)
{
PCLIENT_INFO pClientRunner;
pClientRunner = pServerInfo->pClientInfoList;
while(pClientRunner)
{
if(pClientRunner != pClientInfo)
{
send(pClientRunner->hSocket, pszBuffer, strlen(pszBuffer) + 1, 0);
}
pClientRunner = pClientRunner->Next;
}
}
/**********************************************************************
*
* Serv_SendNewClientBroadCast
*
* Send All Connected Client Information to New Client
*
**********************************************************************/
void Serv_SendNewClientBroadCast(SOCKET hClientSocket, PSERVER_INFO pServerInfo)
{
char szBuffer[5000] = {0};
PCLIENT_INFO pClientInfo;
sprintf(szBuffer, "People Connected: ");
pClientInfo = pServerInfo->pClientInfoList;
while(pClientInfo)
{
sprintf(szBuffer, "%s %s", szBuffer, pClientInfo->Nick);
pClientInfo = pClientInfo->Next;
}
sprintf(szBuffer, "%s\n", szBuffer);
send(hClientSocket, szBuffer, strlen(szBuffer), 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -