Listing 2: Implementation of CComm class

//developed for C/C++ Users Journal by Erik L. Nelson
//this code may be used freely with no restrictions on use

#include "comm.h"

CComm::CComm(){
   ListenSocket=INVALID_SOCKET;
   #ifdef _WIN32
      WORD VersionRequested = MAKEWORD(1,1);
      WSADATA wsaData;
      WSAStartup(VersionRequested, &wsaData);
      if(wsaData.wVersion != VersionRequested){
         printf("Wrong version or WinSock not loaded\n");
         fflush(0);  // make sure the message gets printed out
      }
   #endif
}

CComm::~CComm(){
   if(ListenSocket != INVALID_SOCKET){
      closesocket(ListenSocket);
   }
   #ifdef _WIN32
      WSACleanup();
   #endif
}


bool CComm::SendMsg(char *Msg, int Len, char *host, short port){
   signed int Sent;
   hostent *hostdata;
   if(atoi(host)){
      u_long ip=inet_addr(host);
      hostdata=gethostbyaddr((char *)&ip,sizeof(ip),PF_INET);
   }else // otherwise, assume it is a name
      hostdata=gethostbyname(host);

   if(! hostdata){
      printf("Error getting host address\n");
      fflush(0);
      return false;
   }
   sockaddr_in dest;  // the address of the destination computer
   dest.sin_family = PF_INET;
   dest.sin_addr=*(in_addr *)(hostdata->h_addr_list[0]);
   dest.sin_port = htons(port);
   printf("Message being sent to host %s port %i\n",
      inet_ntoa(dest.sin_addr),ntohs(dest.sin_port)); 
   Sent=sendto(ListenSocket,Msg,Len,0,(sockaddr *)&dest,
           sizeof(sockaddr_in));
   if(Sent != Len){
      printf("Error sending UDP packet from listen socket\n");
      fflush(0);
      return false;
   }
   return true;
}

void *CComm::ListenThread(void *data){
   char buf[4096];
   CComm *Comm=(CComm *)data;
   int len=sizeof(Comm->client);
   while(1){  // loop forever  
      int result=recvfrom(Comm->ListenSocket,buf, sizeof(buf)-1,
         0,(sockaddr *)&Comm->client,(socklen_t *)&len);
      if(result > 0){
         buf[result]=0;
         printf("Message received from host %s port %i\n",
            inet_ntoa(Comm->client.sin_addr),
            ntohs(Comm->client.sin_port));      
         printf("%s",buf);
         fflush(0);
      }  // end check to see if socket read was OK
   }  // end of infinite loop 
}


bool CComm::Listen(int PortNum){
   ListenSocket=socket(PF_INET, SOCK_DGRAM, 0);
   if(ListenSocket == INVALID_SOCKET){
      printf("Error: listen socket creation failed\n");
      return false;
   }
  
   srv.sin_family = PF_INET;
   srv.sin_addr.s_addr = htonl(INADDR_ANY);
   srv.sin_port = htons(PortNum);

   if(bind(ListenSocket, 
         (struct sockaddr *)&srv,sizeof(srv)) != 0){
      printf("Error: bind on listen socket failed\n");
      closesocket(ListenSocket);
      return false;
   }
   int ThreadID;  // the listening thread's handle
   #ifdef _WIN32
      DWORD thread;
      ThreadID = (int)CreateThread(NULL,0,
                    (LPTHREAD_START_ROUTINE)(CComm::ListenThread),
                    (void *)this,0,&thread);
      ThreadID=ThreadID ? 0 : 1;  // reverse the value for Windows
   #else
      pthread_t thread;
      ThreadID=pthread_create(&thread,0,CComm::ListenThread,
                  (void *)this);
   #endif
   if(ThreadID){  // if failed creating thread
      printf("Error creating listen thread\n");
      return false;
   }else{
      return true;
   }
}