Source Code (Use browser search to find items of interest.)

Class Index

kabalone'Network (./kdegames/kabalone/Network.h:28)

class Network: public QObject
{
  Q_OBJECT
    
 public:
  static const int defaultPort = 23412;

  /* install listening TCP socket on port */
  Network(int port = defaultPort);
  ~Network();

  bool isOK() { return (fd>=0); }
  void addListener(const char* host, int port);  
  void broadcast(const char* pos);

 signals:
  void gotPosition(const char* pos);

 private slots:
  void gotConnection();
  
 private:
  bool sendString(struct sockaddr_in sin, char* str, int len);

  QList<Listener> listeners;
  struct sockaddr_in mySin;
  int fd, myPort;
  QSocketNotifier *sn;
};

kabalone'Network::Network() (./kdegames/kabalone/Network.cpp:28)

Network::Network(int port)
{
  struct sockaddr_in name;
  int i,j;

  listeners.setAutoDelete(TRUE);

  fd = ::socket (PF_INET, SOCK_STREAM, 0);
  if (fd<0) return;
 
  for(i = 0; i<5;i++) {
    name.sin_family = AF_INET;
    name.sin_port = htons (port+i);
    name.sin_addr.s_addr = htonl (INADDR_ANY);
    if (bind (fd, (struct sockaddr *) &name, sizeof (name)) >= 0)
      break;
    //    printf("...Port %d in use\n", port+i);
  }
  mySin = name;
  //  printf("I'm using Port %d\n", port+i);
  if (i==5) {
    printf("Error in bind to port %d\n", port);
    close(fd);
    fd = -1;
    return;
  }     
  for(j = 0; j<i;j++)
    addListener("127.0.0.1", port+j);

  if (::listen(fd,5)<0) {
    printf("Error in listen\n");
    close(fd);
    fd = -1;
    return;
  }

  sn = new QSocketNotifier( fd, QSocketNotifier::Read );
  QObject::connect( sn, SIGNAL(activated(int)),
		    this, SLOT(gotConnection()) );
}


kabalone'Network::~Network() (./kdegames/kabalone/Network.cpp:69)

Network::~Network()
{
  if (fd<0) return;
  close(fd);

  char tmp[50];
  int len = sprintf(tmp, "unreg %d", ntohs(mySin.sin_port));
  
  Listener* l;
  for(l=listeners.first(); l!=0; l=listeners.next()) {
    if (l->reachable)
      sendString( l->sin, tmp, len);
  }
  listeners.clear();

  delete sn;
}


kabalone'Network::gotConnection() (./kdegames/kabalone/Network.cpp:87)

void Network::gotConnection()
{
  static char tmp[1024];
  int len=0;
  struct sockaddr_in sin;
  ksize_t sz = sizeof (sin);

  //  printf("GotConnection: ");
  int s = accept(fd,(struct sockaddr *)&sin, &sz);
  if (s<0) {
    printf("Error in accept\n");
    return;
  }
  while(read(s, tmp+len, 1)==1) len++;
  close(s);
  tmp[len]=0; len++;
  //  printf("Got: '%s'\n",tmp);
  if (strncmp(tmp,"reg ",4)==0) {
    int port = atoi(tmp+4);
    sin.sin_port = htons( port );
    Listener *l = new Listener(0,0,sin);
    //    printf("Reg of 0x%x:%d\n", 
    //	   ntohl(sin.sin_addr.s_addr ), ntohs(sin.sin_port));
    listeners.append(l);
    return;
  }

  if (strncmp(tmp,"unreg ",6)==0) {
    int port = atoi(tmp+6);
    sin.sin_port = htons( port );
    Listener* l;
    for(l=listeners.first(); l!=0; l=listeners.next())
      if (l->sin.sin_addr.s_addr == sin.sin_addr.s_addr &&
	  l->sin.sin_port == sin.sin_port) break;
    if (l==0) {
      printf("Error: UnReg of 0x%x:%d. Not Found\n",
	     ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
      return;
    }
    listeners.remove(l);
    //    printf("UnReg of 0x%x:%d\n",
    //	   ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
    return;
  }

  if (strncmp(tmp,"pos ",4)==0) {
    emit gotPosition(tmp+4);
  }
}


kabalone'Network::addListener() (./kdegames/kabalone/Network.cpp:137)

void Network::addListener(const char* host, int port)
{
  struct hostent *hostinfo;
  struct sockaddr_in name;
  
  name.sin_family = AF_INET;
  name.sin_port = htons (port);
  hostinfo = gethostbyname (host);
  if (hostinfo == NULL) {
    printf ("Error in addListener: Unknown host %s.\n", host);
    return;
  }
  name.sin_addr = *(struct in_addr *) hostinfo->h_addr;

  Listener *l = new Listener(host,port,name);
//  printf("Added Listener %s, 0x%x:%d\n", 
//	 host, ntohl(name.sin_addr.s_addr), ntohs(name.sin_port));
  listeners.append(l);

  char tmp[50];
  int len = sprintf(tmp, "reg %d", ntohs(mySin.sin_port));

  if (!sendString( name, tmp, len))
    listeners.remove(l);
}


kabalone'Network::broadcast() (./kdegames/kabalone/Network.cpp:163)

void Network::broadcast(const char* pos)
{
  char tmp[1024];
  int len = sprintf(tmp,"pos %s", pos);
  
  for(Listener* l=listeners.first(); l!=0; l=listeners.next())
    if (l->reachable)
      l->reachable = sendString(l->sin, tmp, len);
}


kabalone'Network::sendString() (./kdegames/kabalone/Network.cpp:173)

bool Network::sendString(struct sockaddr_in sin, char* str, int len)
{
  int s = ::socket (PF_INET, SOCK_STREAM, 0);
  if (s<0) {
    printf("Error in sendString/socket ??\n");
    return false;
  }
  if (::connect (s, (struct sockaddr *)&sin, sizeof (sin)) <0) {
    printf("Error in sendString/connect to socket 0x%x:%d\n", 
	   ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port) );
    return false;
  }
  write(s, str, len);
  close(s);
  //  printf("Send '%s' to 0x%x:%d\n", str, 
  //	 ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port) );
  return true;
}