现在的位置: 首页 > 综合 > 正文

UDP服务器

2017年12月07日 ⁄ 综合 ⁄ 共 11150字 ⁄ 字号 评论关闭

 

#include "StdAfx.h" 
#include 
<winsock2.h> 
#include 
<ws2tcpip.h> 
#include 
"Stdio.h" 

#define BUFSIZE 1024 //max size of incoming data buffer 
#define MAXADDRSTR 16 

#define DEFAULT_GROUP_ADDRESS "239.254.1.2" 
#define DEFAULT_PORT 7125  

LONG nCount = 0
HANDLE g_hCompletionPort; 

DWORD WINAPI WorkerThread( LPVOID WorkContext ); 

BOOL HandleIncomingData( UCHAR* pBuf); 
BOOL CreateNetConnections( VOID ); 
BOOL CreateWorkers( UINT ); 
void InitWinsock2(); 
void UnInitWinsock2(); 

HANDLE g_hReadEvent; 
SOCKET g_hSocket; 
UCHAR achInBuf [BUFSIZE]; 
char achMCAddr[MAXADDRSTR] = DEFAULT_GROUP_ADDRESS; 
u_short nPort 
= DEFAULT_PORT; 

OVERLAPPED Overlapped; 
 //----------------------------------------------------------------------------- 
void InitWinsock2() 
{  
             WSADATA data;  
             WORD version;  
             
int ret = 0;   

             version = (MAKEWORD(22));  
             ret 
= WSAStartup(version, &data);  
             
if (ret != 0)  
             {   
                          ret 
= WSAGetLastError();  
                          
if (ret == WSANOTINITIALISED)  
                          {   
                                       printf(
"not initialised");  
                          } 
            } 

//----------------------------------------------------------------------------- 
void UnInitWinsock2() 
{  
           WSACleanup(); 

//----------------------------------------------------------------------------- 
BOOL CreateNetConnections (void
{  
             DWORD nbytes;  
             BOOL b;  
             BOOL fFlag 
= TRUE;  
             
int nRet=0;  
             SOCKADDR_IN stLclAddr;   
             
struct ip_mreq stMreq; // Multicast interface structure   

             // Get a datagram socket   
             g_hSocket = socket(AF_INET, SOCK_DGRAM,0);  
             
if (g_hSocket == INVALID_SOCKET)   
             {  
                          printf (
"socket() failed, Err: %d ", WSAGetLastError());  
                          
return FALSE;   
             }   

             nRet = setsockopt(g_hSocket,SOL_SOCKET,SO_REUSEADDR, (char *)&fFlag, sizeof(fFlag));   
             
if (nRet == SOCKET_ERROR)   
             {  
                          printf (
"setsockopt() SO_REUSEADDR failed, Err: %d ",WSAGetLastError());  
             }  

             // Name the socket (assign the local port number to receive on)   
             stLclAddr.sin_family = AF_INET;  
             stLclAddr.sin_addr.s_addr 
= htonl(INADDR_ANY);  
             stLclAddr.sin_port 
= htons(nPort);  
             nRet 
= bind(g_hSocket,(struct sockaddr*&stLclAddr,sizeof(stLclAddr));  
             
if (nRet == SOCKET_ERROR)   
             {  
                          printf (
"bind() port: %d failed, Err: %d ", nPort,WSAGetLastError());  
             }  

             // Join the multicast group so we can receive from it   
             stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr);  
             stMreq.imr_interface.s_addr 
= INADDR_ANY;  
             nRet 
= setsockopt(g_hSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&stMreq,sizeof             (stMreq));  
             
if (nRet == SOCKET_ERROR)   
             {  
             printf(
"setsockopt() IP_ADD_MEMBERSHIP address %s failed, Err: %d ",achMCAddr,                     WSAGetLastError());  
             }   

             //  
             
// note the 10 says how many concurrent cpu bound threads to allow thru  
             
// this should be tunable based on the requests. CPU bound requests will  
             
// really really honor this.  
             
//  

             g_hCompletionPort 
= CreateIoCompletionPort (INVALID_HANDLE_VALUE,NULL,0,3);  
             
if (!g_hCompletionPort)  
             {  
                          fprintf (stdout, 
"g_hCompletionPort Create Failed ");  
                          
return FALSE;  
             }  

             //Associate this socket to this I/O completion port  
             CreateIoCompletionPort ((HANDLE)g_hSocket,g_hCompletionPort,(DWORD)g_hSocket,3);   

             //   
             
// Start off an asynchronous read on the socket.   
             
//   

             Overlapped.hEvent 
= g_hReadEvent;   
             Overlapped.Internal 
= 0;   
             Overlapped.InternalHigh 
= 0;   
             Overlapped.Offset 
= 0;   
             Overlapped.OffsetHigh 
= 0;   

             b = ReadFile ((HANDLE)g_hSocket,&achInBuf,sizeof (achInBuf),&nbytes,&Overlapped);   

             if (!&& GetLastError () != ERROR_IO_PENDING)   
             {   
                          fprintf (stdout, 
"ReadFile Failed ");   
                          
return FALSE;   
             }   

             return TRUE; 

//----------------------------------------------------------------------------- 
BOOL CreateWorkers (UINT dwNumberOfWorkers) 
{  
        DWORD ThreadId;  
        HANDLE ThreadHandle;  
        DWORD i;  

        for (i = 0; i < dwNumberOfWorkers; i++)  
        {  
                ThreadHandle 
= CreateThread (NULL,0,WorkerThread,NULL,0,&ThreadId);  
                
if (!ThreadHandle)  
                {  
                        fprintf (stdout, 
"Create Worker Thread Failed ");  
                        
return FALSE;  
                }  

                CloseHandle (ThreadHandle);  
        }  

        return TRUE; 

//----------------------------------------------------------------------------- 
DWORD WINAPI WorkerThread (LPVOID WorkContext) 
{  

        DWORD nSocket;  
        BOOL b;  
        OVERLAPPED ovl;  
        LPOVERLAPPED lpo=&ovl;  
        DWORD nBytesRead
=0;  
        DWORD nBytesToBeRead;  
        UCHAR ReadBuffer[BUFSIZE];  
        LPVOID lpMsgBuf;  

        memset(&ReadBuffer,0,BUFSIZE);  

        for (;;)  
        {  

                b = GetQueuedCompletionStatus (g_hCompletionPort,&nBytesToBeRead,&nSocket,&lpo,INFINITE);  

                if (b || lpo)  
                {  
                        
if (b)  
                        {  
                                
//  
                                
// Determine how long a response was desired by the client.  
                                
//  
                                OVERLAPPED ol;  
                                ol.hEvent 
= g_hReadEvent;  
                                ol.Offset 
= 0;  
                                ol.OffsetHigh 
= 0;  

                                b = ReadFile ((HANDLE)nSocket,&ReadBuffer,nBytesToBeRead,&nBytesRead,&ol);  
                                
if (!b )   
                                {  
                                               DWORD dwErrCode 
= GetLastError();  
                                               
if( dwErrCode != ERROR_IO_PENDING )  
                                               {  
                                                    
// something has gone wrong here...  
                                                    printf("Something has gone wrong:Error code - %d ",dwErrCode );  

                                                    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |   
                                                    FORMAT_MESSAGE_FROM_SYSTEM 
|   
                                                                                                FORMAT_MESSAGE_IGNORE_INSERTS,  
                                                                                                NULL,  
                                                                                                dwErrCode ,  
                                                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
// Default language  
                                                                                                (LPTSTR) &lpMsgBuf,  
                                                                                                
0,  
                                                                                                NULL   
                                                                                                           );  

                                                    OutputDebugString((LPCTSTR)lpMsgBuf);  

                                                    // Free the buffer.  
                                                    LocalFree( lpMsgBuf );  
                                }  
                                
else  
                                
if( dwErrCode == ERROR_IO_PENDING )  
                                { 

                                      // I had to do this for my UDP sample 

                                      //Never did for my TCP servers  
                                      WaitForSingleObject(ol.hEvent,INFINITE);   

                                      HandleIncomingData(ReadBuffer);  
                                 } 
                        }  
                        else  
                        {  
                                                HandleIncomingData(ReadBuffer);  
                        }  

                        continue
            } 
           
else  
           {  
           fprintf (stdout, 
"WorkThread Wait Failed ");  
           
//exit (1);  
           } 
        } 
       
return 1
      } 

//----------------------------------------------------------------------------- 
BOOL HandleIncomingData( UCHAR* pBuf) 
{  
           InterlockedIncrement(
&nCount);  
           SYSTEMTIME 
*lpstSysTime;  
           lpstSysTime 
= (SYSTEMTIME *)(pBuf);  

           printf("[%d]UTC Time %02d:%02d:%02d:%03d on %02d-%02d-%d  ",nCount,  
           lpstSysTime
->wHour, lpstSysTime->wMinute,   
           lpstSysTime
->wSecond, lpstSysTime->wMilliseconds,  
           lpstSysTime
->wMonth, lpstSysTime->wDay, lpstSysTime->wYear);  

           memset(&pBuf,0,BUFSIZE); //just making sure that i am not showing stale data  

           
return TRUE; 

//----------------------------------------------------------------------------- 
main () 
{  
           
//You can modify your program to take some arguments for port number  
           
//and multicast group address here  
           printf(" *************************************** ");  
           printf(
"Group IP address: %s ",achMCAddr);  
           printf(
"Port number : %d ",nPort);  
           printf(
" *************************************** ");  

           //Initialize winsock 2   
           InitWinsock2();  

           //We want to keep the main thread running  
           HANDLE hWait2Exit = CreateEvent(NULL,FALSE,TRUE,"MCLIENT");  
           ResetEvent(hWait2Exit );  

           //This OVERLAPPED event  
           g_hReadEvent = CreateEvent(NULL,TRUE,TRUE,NULL);   

           //  
           
// try to get timing more accurate... Avoid context  
           
// switch that could occur when threads are released  
           
//  

           SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);  

           if (!CreateNetConnections ())  
           {  
                      printf(
"Error condition @ CreateNetConnections , exiting ");  
                      
return 1;  
           }  

           if (!CreateWorkers (5))  
           {  
                      printf(
"Error condition @CreateWorkers, exiting ");  
                      
return 1;  
           }  

           WaitForSingleObject(hWait2Exit,INFINITE);  

           UnInitWinsock2();  

           return 1

抱歉!评论已关闭.