// 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; }
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");; }
// 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; }