teTCPError TCPServerConnection::disconnect( void )
{
  if (!listening())
    return setError(eTCPSocketNFG);

  std::map<TCPsocket,TCPServerConnectedPeer>::iterator itr = peers.begin();

  while ( itr != peers.end() )
  {
    for ( unsigned int i = 0; i < dataPendingList.size(); i++ )
      dataPendingList[i]->disconnect(this,&itr->second,true);

    net_TCP_Close(itr->first);
    net_DelSocket(socketSet,(net_GenericSocket)itr->first);
  }

  peers.clear();

  net_TCP_Close(socket);
  net_DelSocket(socketSet,(net_GenericSocket)socket);

  net_FreeSocketSet(socketSet);

  socketSet = NULL;
  socket = NULL;

  return setError(eTCPNoError);
}
bool TCPServerConnection::disconectPeer ( TCPServerConnectedPeer* peer )
{
  if (!peer)
    return false;

  std::map<TCPsocket,TCPServerConnectedPeer>::iterator itr = peers.begin(), itr2 = peers.begin();

  while ( itr != peers.end() )
  {
    if (&itr->second == peer )
    {
      // they got discoed.
      for ( unsigned int i = 0; i < dataPendingList.size(); i++ )
        dataPendingList[i]->disconnect(this,peer,true);

      net_TCP_DelSocket(socketSet, itr->first);
      net_TCP_Close(itr->first);

      itr2 = itr;
      itr2++;
      peers.erase(itr);
      itr = itr2;
      return true;
    }
    itr++;
  }
  return false;
}
Beispiel #3
0
/* Accept an incoming connection on the given server socket.
The newly created socket is returned, or NULL if there was an error.
*/
TCPsocket net_TCP_Accept(TCPsocket server)
{
  TCPsocket sock;
  struct sockaddr_in sock_addr;
  socklen_t sock_alen;

  /* Only server sockets can accept */
  if ( ! server->sflag ) {
    net_SetError("Only server sockets can accept()");
    return(NULL);
  }
  server->ready = 0;

  /* Allocate a TCP socket structure */
  sock = (TCPsocket)malloc(sizeof(*sock));
  if ( sock == NULL ) {
    net_SetError("Out of memory");
    goto error_return;
  }

  /* Accept a new TCP connection on a server socket */
  sock_alen = sizeof(sock_addr);
  sock->channel = accept(server->channel, (struct sockaddr *)&sock_addr,
#ifdef USE_GUSI_SOCKETS
    (unsigned int *)&sock_alen);
#else
    &sock_alen);
#endif
  if ( sock->channel == SOCKET_ERROR ) {
    net_SetError("accept() failed");
    goto error_return;
  }
#ifdef WIN32
  {
    /* passing a zero value, socket mode set to block on */
    unsigned long mode = 0;
    ioctlsocket (sock->channel, FIONBIO, &mode);
  }
#endif /* WIN32 */
  sock->remoteAddress.host = sock_addr.sin_addr.s_addr;
  sock->remoteAddress.port = sock_addr.sin_port;

  sock->sflag = 0;
  sock->ready = 0;

  /* The socket is ready */
  return(sock);

error_return:
  net_TCP_Close(sock);
  return(NULL);
}
teTCPError TCPClientConnection::disconnect( void )
{
  if (!connected())
    return setError(eTCPSocketNFG);

  net_TCP_Close(socket);
  socket = NULL;

  if (parent)
    parent->removeClientSocket(this);

  return setError(eTCPNoError);
}
bool TCPServerConnection::update ( void )
{
  if (net_CheckSockets(socketSet, ~0) < 1)
    return true;

  // see if our boys have any new connections
  if ( net_SocketReady(socket) )
  {
    TCPsocket    newsock;

    newsock = net_TCP_Accept(socket);
    while ( newsock != NULL )
    {
      TCPServerConnectedPeer  peer;
      peer.connect(newsock);
      peers[newsock] = peer;

      bool accept = true;
      for ( unsigned int i = 0; i < dataPendingList.size(); i++ )
      {
        if ( !dataPendingList[i]->connect(this,&(peers[newsock])) )
          accept = false;
      }
      if (accept)
        net_TCP_AddSocket(socketSet, newsock);
      else
      {
        peers.erase(peers.find(newsock));
        net_TCP_Close(newsock);
      }

      newsock = net_TCP_Accept(socket);
    }
  }

  std::map<TCPsocket,TCPServerConnectedPeer>::iterator itr = peers.begin(), itr2 = peers.begin();

  while ( itr != peers.end() )
  {
    if (net_SocketReady(itr->first))
    {
      if (itr->second.readData())
      {
        if ( itr->second.getPacketCount())
        {
          for ( unsigned int i = 0; i < dataPendingList.size(); i++ )
            dataPendingList[i]->pending(this,&itr->second,itr->second.getPacketCount());
        }
        itr++;
      }
      else
      {
        // they got discoed.
        for ( unsigned int i = 0; i < dataPendingList.size(); i++ )
          dataPendingList[i]->disconnect(this,&itr->second);

        net_TCP_DelSocket(socketSet, itr->first);
        net_TCP_Close(itr->first);

        itr2 = itr;
        itr2++;
        peers.erase(itr);
        itr = itr2;
        return true;
      }
    }
    else
      itr++;
  }

  return true;
}
Beispiel #6
0
/* Open a TCP network socket
If 'remote' is NULL, this creates a local server socket on the given port,
otherwise a TCP connection to the remote host and port is attempted.
The newly created socket is returned, or NULL if there was an error.
*/
TCPsocket net_TCP_Open(IPaddress *ip)
{
  TCPsocket sock;
  struct sockaddr_in sock_addr;

  /* Allocate a TCP socket structure */
  sock = (TCPsocket)malloc(sizeof(*sock));
  if ( sock == NULL ) {
    net_SetError("Out of memory");
    goto error_return;
  }

  /* Open the socket */
  sock->channel = socket(AF_INET, SOCK_STREAM, 0);
  if ( sock->channel == INVALID_SOCKET ) {
    net_SetError("Couldn't create socket");
    goto error_return;
  }

  /* Connect to remote, or bind locally, as appropriate */
  if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) ) {

    // #########  Connecting to remote

    memset(&sock_addr, 0, sizeof(sock_addr));
    sock_addr.sin_family = AF_INET;
    sock_addr.sin_addr.s_addr = ip->host;
    sock_addr.sin_port = ip->port;

    /* Connect to the remote host */
    if ( connect(sock->channel, (struct sockaddr *)&sock_addr,
      sizeof(sock_addr)) == SOCKET_ERROR ) {
        net_SetError("Couldn't connect to remote host");
        goto error_return;
      }
      sock->sflag = 0;
  } else {

    // ##########  Binding locally

    memset(&sock_addr, 0, sizeof(sock_addr));
    sock_addr.sin_family = AF_INET;
    sock_addr.sin_addr.s_addr = INADDR_ANY;
    sock_addr.sin_port = ip->port;

    /* allow local address reuse */
    { int yes = 1;
    setsockopt(sock->channel, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes));
    }

    /* Bind the socket for listening */
    if ( bind(sock->channel, (struct sockaddr *)&sock_addr,
      sizeof(sock_addr)) == SOCKET_ERROR ) {
        net_SetError("Couldn't bind to local port");
        goto error_return;
      }
      if ( listen(sock->channel, 5) == SOCKET_ERROR ) {
        net_SetError("Couldn't listen to local port");
        goto error_return;
      }
#ifdef O_NONBLOCK
      /* Set the socket to non-blocking mode for accept() */
      fcntl(sock->channel, F_SETFL, O_NONBLOCK);
#else
#ifdef WIN32
      {
        /* passing a non-zero value, socket mode set non-blocking */
        unsigned long mode = 1;
        ioctlsocket (sock->channel, FIONBIO, &mode);
      }
#else
#warning How do we set non-blocking mode on other operating systems?
#endif /* WIN32 */
#endif /* O_NONBLOCK */

      sock->sflag = 1;
  }
  sock->ready = 0;

#ifdef TCP_NODELAY
  /* Set the nodelay TCP option for real-time games */
  { int yes = 1;
  setsockopt(sock->channel, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes));
  }
#endif /* TCP_NODELAY */

  /* Fill in the channel host address */
  sock->remoteAddress.host = sock_addr.sin_addr.s_addr;
  sock->remoteAddress.port = sock_addr.sin_port;

  /* The socket is ready */
  return(sock);

error_return:
  net_TCP_Close(sock);
  return(NULL);
}