Code:
/////////////////////////////////////////////////////////////////////////////////////////
// LAN status
// quick check network status
BOOL CheckNetwork(void)
{ DWORD ct;
return IsNetworkAlive(&ct) & (GetLastError() == 0); }
// wait until network is connected
BOOL WaitNetwork(BYTE Tries,BYTE Delay)
{ BYTE rt = 0; // retry count
while (!CheckNetwork())
{ if (++rt > Tries)
return 0;
Sleep(Delay * 1000); }
return 1; }
/////////////////////////////////////////////////////////////////////////////////////////
// send datagrams
//
// compose and send datagrams
BOOL SendDatagram(PSOCKADDR To,DWORD PassCode,BYTE Command,PVOID Data,INT DataSize)
{ DATAGRAM dgram = {0}; // blank datagram
INT sdgram; // datagram size
FD_SET st; // socket to be tested
TIMEVAL tv; // delay time for test
// insert passcode
dgram.PassCode = PassCode;
// insert command
dgram.Command = Command;
// copy data
if (DataSize > 0)
memcpy(&dgram.Data,Data,DataSize);
// calculate size
sdgram = ((DWORD)&dgram.Data - (DWORD)&dgram) + DataSize + sizeof(TCHAR);
// wait then send
st.fd_count = 1;
st.fd_array[0] = hSocket;
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(1,NULL,&st,NULL,&tv) > 0)
if (sendto(hSocket,(PCHAR)&dgram,sdgram,0,To,sizeof(SOCKADDR)) > 0)
return 1;
return 0; }
/////////////////////////////////////////////////////////////////////////////////////////
// Receive Datagrams
//
// datagram tosser prototype
BOOL CALLBACK (*Toss)(PSOCKADDR,DWORD,BYTE,LPVOID);
// receiver thread
DWORD Listener(LPVOID DgramTosser)
{ DATAGRAM dgram; // blank datagram
INT sdg; // size of datagram
SOCKADDR from; // return address
INT sf; // size of reply addr
// set callback
Toss = DgramTosser;
// receiver loop
while(!KillWSA)
{ // clear old data
memset(&dgram,0,sizeof(DATAGRAM));
// set address size
sf = sizeof(SOCKADDR);
// receive datagram
sdg = recvfrom(hSocket,(PCHAR)&dgram,sizeof(DATAGRAM),0,&from,&sf);
// hand to tosser
if (sdg > 0)
{ Toss(&from,dgram.PassCode,dgram.Command,&dgram.Data); } }
return WSAGetLastError(); }
// resolve server name and port to useable LAN addr
BOOL GetHostAddr(PTCHAR Name, WORD Port, PSOCKADDR Addr, BYTE Tries, BYTE Delay)
{ ADDRINFOT hints = {0}; // hints for search
PADDRINFOT res = NULL; // pointer to search result
BYTE rt = 0; // retry count
// wait for connection
WaitNetwork(20,1);
// fill in struct
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
// get ip address
while(GetAddrInfo(Name,NULL,&hints,&res))
{ if (++rt > Tries)
return 0;
Sleep(Delay * 1000); }
// transfer to local IP struct
memcpy(Addr,res->ai_addr,sizeof(SOCKADDR));
((PSOCKADDR_IN) Addr)->sin_family = AF_INET;
((PSOCKADDR_IN) Addr)->sin_port = htons(Port);
// release memory
FreeAddrInfo(res);
return 1; }
// for incremental port search
VOID SetHostPort(WORD Port,PSOCKADDR Addr)
{ ((PSOCKADDR_IN) Addr)->sin_port = htons(Port);
((PSOCKADDR_IN) Addr)->sin_family = AF_INET; }
/////////////////////////////////////////////////////////////////////////////////////////
// start and stop
//
// initialize Client port/return port number
WORD InitNetwork(WORD Port,BOOL Scan,LPVOID DgramTosser )
{ WSADATA wsadata; // winsock startup
TCHAR hn[MAX_HOSTNAME]; // host name
DWORD hs = MAX_HOSTNAME; // host name size
SOCKADDR la; // local address
INT x = 0; // counter
ULONG bl = 0; // blocking flag
WORD lp = Port; // local port
// Load the Winsock DLL
if (WSAStartup(MAKEWORD(2,0),&wsadata))
return 0;
// initialize local socket
hSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (hSocket == INVALID_SOCKET)
return 0;
// set full blocking mode
ioctlsocket(hSocket,FIONBIO,&bl);
// initialize localhost IP
GetComputerName(hn,&hs);
if (!GetHostAddr(hn,Port,&la,10,1))
return 0;
// bind on user designated Port
while(bind(hSocket,&la,sizeof(SOCKADDR)))
{ if (!Scan)
return 0;
SetHostPort(++lp,&la);
if (lp > (Port + 256))
return 0; }
// launch the listener thread
KillWSA = FALSE;
hReceiver = CreateThread(NULL,0,&Listener,DgramTosser,0,NULL);
if (hReceiver == NULL)
return 0;
return lp; }
// shut down the network
VOID KillNetwork(void)
{ //let packets clear
Sleep(100);
// stop receiver
KillWSA = TRUE;
// teminate the receiver
TerminateThread(hReceiver,0);
// close the socket
shutdown(hSocket,SD_BOTH);
closesocket(hSocket);
// let winsock close
Sleep(100);
// cleanup handles
WSACleanup();
CloseHandle(hReceiver); }