示例#1
0
// Create a server socket and bind it to a specific port
// 1. Input:
//  <0> port
//  <1> type
//    - AF_INET  : IPv4
//    - AF_INET6 : IPv6
//  <2> backlog : specify the max length of connection pending queue.
// 2. Output:
//  <1> ret : Server Socket FD if success else -1
int CreateServerSocket(const char *port, int type, int backlog) {
  if (!port) {
    app_error("Server port should be filled.\n");
    return -1;
  }

  // prepare address struct
  struct addrinfo hints, *server_info = NULL;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = type;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;

  int ret;
  if ((ret = getaddrinfo(NULL, port, &hints, &server_info)) != 0) {
    ai_error(ret);
    return -1;
  }

  // Loop through all the results and bind the first we can
  int sock_fd;
  struct addrinfo *p;
  for (p = server_info; p != NULL; p = p->ai_next) {
    if ((sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
      perror("server: socket");
      continue;
    }
    // SO_REUSERADDR: Allows other sockets to bind() to this port, unless
    // there is an active listening socket boud to the port already
    int yes = 1;
    if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
      unix_error("setsockopt");
    }
    if (bind(sock_fd, p->ai_addr, p->ai_addrlen) == -1) {
      close(sock_fd);
      perror("server: bind");
      continue;
    }
    break;
  }

  if (!p) {
    app_error("server: failed to create socket on port %s\n", port);
    if (server_info) {
      freeaddrinfo(server_info);
    }
    return -1;
  }

  freeaddrinfo(server_info);

  // backlog sepcifies how many pending connections you can have before the
  // kernel starts rejecting new ones.
  if (listen(sock_fd, backlog)) {
    unix_error("server failed to bind.");
  }

  return sock_fd;
}
示例#2
0
float AStar::get_cost(astar::Node* node1, astar::Node* node2)
{
	navigation_graph::LinkIterator it = node1->navidata->links.begin();
	for(; it != node1->navidata->links.end(); it++){
		if((*it).node_id == node2->navidata->id)
			return (*it).cost;
	}	

	throw ai_error("Navigation graph error");;
}
示例#3
0
// Try to connect to a remote sever using SOCK_STREAM
// 1. Input:
//  <1> host : server host name or ip address
//  <2> port : server port
//  <3> timeout : in ms
//    - if < 0 block forever
//    - if = 0 non-block
//    - if > 0 timeout
//  <4> retry : currently doesn't support
// 2. Output
//  <2> if success return sock_fd, else return -1
int ConnectTo(const char* host, const char* port, int timeout, int retry) {
  if (!host || !port) {
    app_error("server address or port cannot be empty!.\n");
    return -1;
  }

  // given server address and port number, return the basic info about the
  // server
  struct addrinfo hints, *server_info = NULL;
  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  int ret;
  if ((ret = getaddrinfo(host, port, &hints, &server_info)) != 0) {
    ai_error(ret);
    return -1;
  }

  // Timeout Settings
  struct timeval tv, *tv_ptr;
  if (timeout < 0) {
    tv_ptr = NULL;
  } else {
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = timeout % 1000;
    tv_ptr = &tv;
  }

  // Loop through all the results and connect to the first we can
  fd_set write_fds;
  int sock_fd;
  struct addrinfo* p;
  for (p = server_info; p != NULL; p = p->ai_next) {
    if ((sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
      perror("client: socket");
      continue;
    }

    if (SetSockNonBlocking(sock_fd) < 0) {
      close(sock_fd);
      unix_error("ConnectTo: SetSockNonBlocking:");
    }

    if (connect(sock_fd, p->ai_addr, p->ai_addrlen) < 0) {
      if (errno == EINPROGRESS) {
        FD_ZERO(&write_fds);
        FD_SET(sock_fd, &write_fds);
        switch (select(sock_fd + 1, NULL, &write_fds, NULL, tv_ptr)) {
          case -1:
            perror("ConnectTo: select:");
            close(sock_fd);
            continue;

          case 0:
          DebugStr("ConnectTo: select: timeout\n");
            close(sock_fd);
            continue;
        }

        int error;
        socklen_t len = sizeof(error);

        if (getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)  {
          perror("ConnectTo: getsockopt");
          close(sock_fd);
          continue;
        }

        if (error) {
          DebugStr("ConnectTo: %s\n", strerror(error));
          close(sock_fd);
          continue;
        }

      } else {
        DebugStr("ConnectTo: connect:");
        close(sock_fd);
        continue;
      }
    }
    break;
  }

  if (!p) {
    DebugStr("failed to connect to (%s, %s)\n", host, port);
    if (server_info) {
      freeaddrinfo(server_info);
    }
    return -1;
  }

  if (SetSockBlocking(sock_fd) < 0) {
    close(sock_fd);
    unix_error("ConnectTo: SetSockBlocking");
  }

  {
    const int MAXSIZE = 100;
    char *str = Malloc(MAXSIZE);
    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
              str, MAXSIZE);
    DebugStr("connected to %s\n", str);
    freeaddrinfo(server_info);
    Free(str);
  }
  return sock_fd;
}