📄 server.c
字号:
#include "Server.h"
BOOL g_isMainThreadContinue = FALSE ;
BOOL g_isWorkThreadContinue = FALSE ;
HANDLE g_hMainThreadEndEvent = NULL;
char g_strIpAddr[32];
ULONG g_LastError = 0;
THREADCONTEXT g_ThreadContextList[MAX_THREAD];
static SOCKET g_hSocketTimeServer;
/****************************************************************************************/
static SOCKET CreateServiceSocket(unsigned long dwIPAddr, unsigned short wPort)
{
SOCKET hSocket;
SOCKADDR_IN SocketIn;
hSocket = socket( PF_INET , SOCK_STREAM , IPPROTO_TCP );
if( hSocket == INVALID_SOCKET )
{
UpdateLogFile( "创建锁(CreateServiceSocket)失败!" );
return INVALID_SOCKET;
}
SocketIn.sin_family = AF_INET;
SocketIn.sin_addr.s_addr = dwIPAddr ;//htonl (dwIPAddr);
SocketIn.sin_port = htons (wPort);
if( bind( hSocket , (struct sockaddr*)&SocketIn , sizeof( SocketIn ) ) < 0 )
{
closesocket (hSocket);
UpdateLogFile( "bind失败!" );
return INVALID_SOCKET;
}
if( listen( hSocket , 30 ) < 0 )
{
closesocket( hSocket );
UpdateLogFile( "listen失败!" );
return INVALID_SOCKET;
}
return hSocket;
}
DWORD WINAPI WorkThread( LPVOID lpParameter )
{
ULONG ID = (ULONG) lpParameter ;
PTHREADCONTEXT pThreadContext = NULL;
fd_set fdRead;
struct timeval TimeVal;
int nRet;
char* Buffer = NULL;
SYSTEMTIME SystemTime;
ULONG lOffset = 0;
ULONG lFrameLen = 0;
LONGLONG T2 = 0 , T3 = 0;
Buffer = (char*)malloc( MAX_BUFFER );
if( ID >= MAX_THREAD )
{
pThreadContext = (PTHREADCONTEXT)lpParameter ;
}
else
{
pThreadContext = &g_ThreadContextList[ID];
}
while( pThreadContext->isContinue )
{
//看看是否有任务
if( ID < MAX_THREAD )
{
if( WAIT_OBJECT_0 != WaitForSingleObject( pThreadContext->hJobEvent , 0 ) )
{
pThreadContext->isBusy = FALSE;
Sleep( 500 );
continue;
}
ResetEvent( pThreadContext->hJobEvent );
}
memset( Buffer , 0 , MAX_BUFFER );
//有新任务
while( TRUE )
{
FD_ZERO( &fdRead );
FD_SET( pThreadContext->ConnSocket , &fdRead );
TimeVal.tv_sec = 0;
TimeVal.tv_usec = 500;
nRet = select( 0 , &fdRead , NULL , NULL , &TimeVal );
if( SOCKET_ERROR == nRet )
{
g_LastError = ERROR_SELECT;
UpdateLogFile( "Select失败!" );
// TRACE( "select 错误\r\n" );
Sleep( 100 );
continue;
}
if( nRet == 0 )
{
Sleep( 100 );
continue;
}
//接收数据
lFrameLen = 48;
lOffset = 0;
while( lFrameLen > 0 )
{//循环读取数据
nRet = recv( pThreadContext->ConnSocket , Buffer+lOffset , lFrameLen , 0 );
if( SOCKET_ERROR == nRet || 0 == nRet )
{
UpdateLogFile( "本次连接在接收数据时出错!" );
// TRACE( "本次连接在接收数据时出错\r\n" );
closesocket( pThreadContext->ConnSocket );
break;
}
lFrameLen -= nRet ;
lOffset += nRet;
}
if( lFrameLen > 0 )
{//数据没有正确的读到
break;
}
//记录本地时间T2
GetSystemTime( &SystemTime );
SystemTimeToFileTime( &SystemTime , (FILETIME*)&T2 );
//判断数据包的正确性
if( Buffer[0] != 0x1B )
{
UpdateLogFile( "接收的数据错误!" );
// TRACE( "接收的数据错误\r\n" );
closesocket( pThreadContext->ConnSocket );
break;
}
//填充数据包
memcpy( (char*)&Buffer[32] , (char*)&T2 , sizeof( LONGLONG ) );
Buffer[0] = 0x1C;
//取本地时间T3
GetSystemTime( &SystemTime );
SystemTimeToFileTime( &SystemTime , (FILETIME*)&T3 );
memcpy( (char*)&Buffer[40] , (char*)&T3 , sizeof( LONGLONG ) );
//发送数据包
lFrameLen = 48;
lOffset = 0;
while( lFrameLen > 0 )
{//循环发送数据包
nRet = send( pThreadContext->ConnSocket , Buffer+lOffset , lFrameLen , 0 );
if( SOCKET_ERROR == nRet || nRet == 0 )
{
UpdateLogFile( "发送数据错误!" );
// TRACE( "发送数据错误\r\n" );
closesocket( pThreadContext->ConnSocket );
break;
}
lFrameLen -= nRet;
lOffset += nRet;
}
//结束连接
closesocket( pThreadContext->ConnSocket );
break;
}//while( TRUE )
//完成任务
//判断自己是否为临时创建
if( ID >= MAX_THREAD )
{
free( pThreadContext );
break;
}
}//while( pThreadContext->isContinue )
free( Buffer );
if( ID < MAX_THREAD )
SetEvent( g_ThreadContextList[ID].hEndEvent );
return 0;
}
BOOLEAN InitServer(void)
{
WSADATA wsaData;
UINT i = 0;
ULONG lThreadID = 0;
LONG lRet = 0;
// HKEY hKey;
DWORD dwLen = 32;
DWORD dwType = REG_SZ;
/*
//取得注册表信息
lRet = RegOpenKey( HKEY_LOCAL_MACHINE , REG_IPADDR , &hKey );
if( 0 != lRet )
{
printf( "RegOpenKey Failed" );
MessageBox (NULL, "RegOpenKey失败!", "TimeServer", MB_OK|MB_ICONINFORMATION);
return FALSE;
}
lRet = RegQueryValueEx( hKey , "IpAddr" , NULL , &dwType , g_strIpAddr , &dwLen );
if( 0 != lRet )
{
MessageBox (NULL, "RegQueryValueEx失败!", "TimeServer", MB_OK|MB_ICONINFORMATION);
return FALSE;
}
*/
char szCurrentDir[_MAX_PATH];
// char strIpAddr[32];
UpdateLogFile( "Enter InitServer" );
memset( g_strIpAddr , 0 , 32 );
memset( szCurrentDir , 0 , _MAX_PATH );
GetModuleFileName( NULL , szCurrentDir , _MAX_PATH );
*strrchr( (char*)szCurrentDir , '\\' ) = '\0';
strcat( szCurrentDir , "\\config.ini" );
GetPrivateProfileString( "Info" , "IpAddr" , "127.0.0.1" , g_strIpAddr , 32 , szCurrentDir );
UpdateLogFile( g_strIpAddr );
//创建多个工作线程
for( i = 0 ; i < MAX_THREAD ; i ++ )
{
g_ThreadContextList[i].hMutex = CreateMutex( NULL , FALSE , NULL );
if( NULL == g_ThreadContextList[i].hMutex )
{
g_LastError = ERROR_MUTEX;
UpdateLogFile( "创建锁失败!" );
// TRACE( "创建锁失败\r\n" );
return FALSE;
}
g_ThreadContextList[i].hJobEvent = CreateEvent( NULL , TRUE , FALSE , NULL ) ;
if( NULL == g_ThreadContextList[i].hJobEvent )
{
g_LastError = ERROR_EVENT;
UpdateLogFile( "创建事件失败!" );
// TRACE( "创建事件失败\r\n" );
return FALSE;
}
g_ThreadContextList[i].hEndEvent = CreateEvent( NULL , TRUE , FALSE , NULL );
if( NULL == g_ThreadContextList[i].hEndEvent )
{
g_LastError = ERROR_EVENT;
UpdateLogFile( "创建事件失败!" );
// TRACE( "创建事件失败\r\n" );
return FALSE;
}
g_ThreadContextList[i].isContinue = TRUE;
g_ThreadContextList[i].isBusy = FALSE;
if( NULL == CreateThread( NULL , 0 , WorkThread , (LPVOID)i , (DWORD)0 , &lThreadID) )
{
g_LastError = ERROR_THREAD;
UpdateLogFile( "创建线程失败!" );
// TRACE( "创建线程失败\r\n" );
return FALSE;
}
}//for( i = 0 ; i < MAX_THREAD ; i ++ )
if( WSAStartup( 0x0002 , &wsaData ) )
return FALSE;
g_hSocketTimeServer = CreateServiceSocket( inet_addr(g_strIpAddr) , 1025 );
UpdateLogFile( "Exit InitServer" );
return g_hSocketTimeServer != INVALID_SOCKET;
}
/****************************************************************************************/
void ReleaseServer(void)
{
UINT i = 0;
//停止多个线程
for( i = 0 ; i < MAX_THREAD ; i ++ )
{
ResetEvent( g_ThreadContextList[i].hEndEvent );
g_ThreadContextList[i].isContinue = FALSE;
WaitForSingleObject( g_ThreadContextList[i].hEndEvent , INFINITE );
CloseHandle( g_ThreadContextList[i].hJobEvent );
CloseHandle( g_ThreadContextList[i].hEndEvent );
CloseHandle( g_ThreadContextList[i].hMutex );
}
if( g_hSocketTimeServer != INVALID_SOCKET )
closesocket( g_hSocketTimeServer );
WSACleanup ();
}
/****************************************************************************************/
INT ServerHandler(void)
{
ULONG lAddrSize = 0;
struct timeval TimeVal;
fd_set fdRead;
SOCKET ConnSocket;
SOCKADDR_IN ClientAddr;
UINT i = 0;
PTHREADCONTEXT pTempContext = NULL;
ULONG lThreadID = 0;
lAddrSize = sizeof( SOCKADDR );
// UpdateLogFile( "Enter ServerHandler" );
TimeVal.tv_sec = 0;
TimeVal.tv_usec = MUST_WAIT_TIME;
FD_ZERO( &fdRead );
FD_SET( g_hSocketTimeServer , &fdRead );
if( select( 0, &fdRead , NULL , NULL , &TimeVal ) <= 0 )
{
Sleep( 50 );
return 1;
}
// UpdateLogFile( "before accept" );
ConnSocket = accept( g_hSocketTimeServer , (SOCKADDR*)&ClientAddr , &lAddrSize );
// UpdateLogFile( "after accept" );
if( INVALID_SOCKET == ConnSocket )
{
if( WSAEWOULDBLOCK == WSAGetLastError( ) )
{
Sleep( 50 );
return 1;
}
else
{
g_LastError = ERROR_ACCEPT;
UpdateLogFile( "接收连接错误!" );
// TRACE( "接收连接错误\r\n" );
return ERROR_ACCEPT;
}
}
for( i = 0 ; i < MAX_THREAD ; i ++ )
{
if( !g_ThreadContextList[i].isBusy )
break;
}
if( i < MAX_THREAD )
{//找到了
g_ThreadContextList[i].isBusy = TRUE;
g_ThreadContextList[i].ConnSocket = ConnSocket;
SetEvent( g_ThreadContextList[i].hJobEvent );
}
else
{//没有找到,创建临时的
pTempContext = ( PTHREADCONTEXT )malloc( sizeof( THREADCONTEXT ) );
pTempContext->isContinue = TRUE;
pTempContext->ConnSocket = ConnSocket;
if( NULL == CreateThread( NULL , 0 , WorkThread , pTempContext , (DWORD)0 , &lThreadID) )
{
g_LastError = ERROR_TEMPTHREAD;
UpdateLogFile( "创建临时线程失败!" );
// TRACE( "创建临时线程失败\r\n" );
return 1;
}
}
return 1;
}
BOOL UpdateLogFile(LPCTSTR szStr)
{
HANDLE hFile;
char szFileName[_MAX_PATH],szMessage[_MAX_PATH];
// CHAR szTemp[11];
CHAR szCurrentDir[_MAX_PATH];
char szFilePath[_MAX_PATH];
INT nBytesRet;
ULONG lBytesWritten = 0;
SYSTEMTIME SystemTime;
memset( szCurrentDir , 0 , _MAX_PATH );
memset( szFilePath , 0 , _MAX_PATH );
nBytesRet=GetModuleFileName(NULL,szCurrentDir,_MAX_PATH);
*strrchr( (char*)szCurrentDir , '\\' ) = '\0';
memcpy( szFilePath , szCurrentDir , strlen( szCurrentDir ) );
GetLocalTime( &SystemTime );
sprintf( szFileName , "%d-%d-%d" , SystemTime.wYear , SystemTime.wMonth , SystemTime.wDay );
strcat( szFileName , ".log" );
strcat( szFilePath , "\\" );
strcat( szFilePath , szFileName );
hFile = CreateFile( szFilePath ,
GENERIC_READ|GENERIC_WRITE ,
FILE_SHARE_READ ,
NULL ,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL ,
NULL );
if( INVALID_HANDLE_VALUE == hFile )
{
return FALSE;
}
sprintf( szMessage , "%d:%d:%d " , SystemTime.wHour , SystemTime.wMinute , SystemTime.wSecond );
strcat( szMessage , szStr );
strcat( szMessage , "\r\n" );
SetFilePointer( hFile , 0 , NULL , FILE_END );
WriteFile( hFile , szMessage , strlen( szMessage ) , &lBytesWritten , NULL );
CloseHandle( hFile );
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -