Listing 6: NetThread.h


#ifndef _NETTHREAD_
#define _NETTHREAD_

#include <iostream.h>
#include "target.h"

#if TARGET_PLATFORM == WIN32
#include "WinThread.h"
#include <winsock.h>
typedef AWinThread ThreadBase;

#elif TARGET_PLATFORM == UNIX
#include "UNIXThread.h"
#include <sys/socket.h>
typedef AUNIXThread ThreadBase;

#else
#error TARGET_PLATFORM not recognized
#endif

class ANetThread : public ThreadBase {
public:
   ANetThread(const char* addr = NULL);
   virtual ~ANetThread() {closesocket(mSocket);}

   void Write(const char* ch);
   void WritePendingData();

   virtual void Run();
protected:
   const char* mAddr;
   char        mBufIn[100], mBufOut[100];
   SOCKET      mSocket;

   void ReadNewData();
};

ANetThread::ANetThread(const char* addr) {
   mAddr = addr;
   mBufIn[0] =mBufOut[0] = 0;
}

void ANetThread::Run() {
   sockaddr_in saddr;
   int size = sizeof(saddr);

   mSocket = socket(PF_INET, SOCK_STREAM, 0);
   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(3000);
   if (mAddr) {
      saddr.sin_addr.s_addr = inet_addr(mAddr);
      connect(mSocket, (sockaddr*)&saddr, size);
      cout << "Connected! Begin typing." << endl;
   }
   else {
      saddr.sin_addr.s_addr = 0;
      bind(mSocket, (sockaddr*)&saddr, size);
      listen(mSocket, 1);
      mSocket = accept(mSocket, NULL, NULL);
      cout << "Accepted connection!" << endl;
   }

   while(1) {
      CheckStatus();
      ReadNewData();
      WritePendingData();
   }
}

void ANetThread::Write(const char* str) {
   LockHandle();
   strcat(mBufOut, str);
   UnlockHandle();
}

void ANetThread::ReadNewData() {
   fd_set fd;
   struct timeval tv;
   int size;

   FD_ZERO(&fd);
   FD_SET(mSocket, &fd);
   tv.tv_sec = tv.tv_usec = 0;
   if (select(mSocket + 1, &fd,
              NULL, NULL, &tv) > 0) {
      size = recv(mSocket, mBufIn, 99, 0);
      mBufIn[size] = 0;
      if (mBufIn[0] == 'q' && mBufIn[1] == 0) {
         cout << "Connection closed." << endl;
         closesocket(mSocket);
         mSocket = 0;
      }
      else cout << mBufIn << endl;
   }
}

void ANetThread::WritePendingData() {
   LockHandle();
   if (mBufOut[0] != 0) {
      send(mSocket, mBufOut, strlen(mBufOut), 0);
      mBufOut[0] = 0;
   }
   UnlockHandle();
}

#endif
/* End of File */