Should fix socket binding issues in cygwin.
This commit is contained in:
parent
c9aa8c1ed4
commit
ccfcdeba29
2 changed files with 37 additions and 14 deletions
|
@ -463,12 +463,24 @@ Socket::Server::Server(){
|
||||||
/// \param hostname (optional) The interface to bind to. The default is 0.0.0.0 (all interfaces).
|
/// \param hostname (optional) The interface to bind to. The default is 0.0.0.0 (all interfaces).
|
||||||
/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking).
|
/// \param nonblock (optional) Whether accept() calls will be nonblocking. Default is false (blocking).
|
||||||
Socket::Server::Server(int port, std::string hostname, bool nonblock){
|
Socket::Server::Server(int port, std::string hostname, bool nonblock){
|
||||||
|
if (!IPv6bind(port, hostname, nonblock) && !IPv4bind(port, hostname, nonblock)){
|
||||||
|
fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno));
|
||||||
|
sock = -1;
|
||||||
|
}
|
||||||
|
}//Socket::Server TCP Constructor
|
||||||
|
|
||||||
|
/// Attempt to bind an IPv6 socket.
|
||||||
|
/// \param port The TCP port to listen on
|
||||||
|
/// \param hostname The interface to bind to. The default is 0.0.0.0 (all interfaces).
|
||||||
|
/// \param nonblock Whether accept() calls will be nonblocking. Default is false (blocking).
|
||||||
|
/// \return True if successful, false otherwise.
|
||||||
|
bool Socket::Server::IPv6bind(int port, std::string hostname, bool nonblock){
|
||||||
sock = socket(AF_INET6, SOCK_STREAM, 0);
|
sock = socket(AF_INET6, SOCK_STREAM, 0);
|
||||||
if (sock < 0){
|
if (sock < 0){
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno));
|
fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
int on = 1;
|
int on = 1;
|
||||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
@ -489,28 +501,37 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
ret = listen(sock, 100);//start listening, backlog of 100 allowed
|
ret = listen(sock, 100);//start listening, backlog of 100 allowed
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
return;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno));
|
fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
close();
|
close();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Binding %s:%i failed, retrying as IPv4... (%s)\n", hostname.c_str(), port, strerror(errno));
|
fprintf(stderr, "Binding %s:%i failed (%s)\n", hostname.c_str(), port, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
close();
|
close();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempt to bind an IPv4 socket.
|
||||||
|
/// \param port The TCP port to listen on
|
||||||
|
/// \param hostname The interface to bind to. The default is 0.0.0.0 (all interfaces).
|
||||||
|
/// \param nonblock Whether accept() calls will be nonblocking. Default is false (blocking).
|
||||||
|
/// \return True if successful, false otherwise.
|
||||||
|
bool Socket::Server::IPv4bind(int port, std::string hostname, bool nonblock){
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (sock < 0){
|
if (sock < 0){
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Could not create socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno));
|
fprintf(stderr, "Could not create IPv4 socket %s:%i! Error: %s\n", hostname.c_str(), port, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
on = 1;
|
int on = 1;
|
||||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
if (nonblock){
|
if (nonblock){
|
||||||
int flags = fcntl(sock, F_GETFL, 0);
|
int flags = fcntl(sock, F_GETFL, 0);
|
||||||
|
@ -525,26 +546,26 @@ Socket::Server::Server(int port, std::string hostname, bool nonblock){
|
||||||
}else{
|
}else{
|
||||||
inet_pton(AF_INET, hostname.c_str(), &addr4.sin_addr);//set interface, 0.0.0.0 (default) is all
|
inet_pton(AF_INET, hostname.c_str(), &addr4.sin_addr);//set interface, 0.0.0.0 (default) is all
|
||||||
}
|
}
|
||||||
ret = bind(sock, (sockaddr*)&addr4, sizeof(addr4));//do the actual bind
|
int ret = bind(sock, (sockaddr*)&addr4, sizeof(addr4));//do the actual bind
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
ret = listen(sock, 100);//start listening, backlog of 100 allowed
|
ret = listen(sock, 100);//start listening, backlog of 100 allowed
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
return;
|
return true;
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno));
|
fprintf(stderr, "Listen failed! Error: %s\n", strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
close();
|
close();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
#if DEBUG >= 1
|
#if DEBUG >= 1
|
||||||
fprintf(stderr, "IPv4 binding %s:%i also failed, giving up. (%s)\n", hostname.c_str(), port, strerror(errno));
|
fprintf(stderr, "IPv4 binding %s:%i failed (%s)\n", hostname.c_str(), port, strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
close();
|
close();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}//Socket::Server TCP Constructor
|
}
|
||||||
|
|
||||||
/// Create a new Unix Server. The socket is immediately bound and set to listen.
|
/// Create a new Unix Server. The socket is immediately bound and set to listen.
|
||||||
/// A maximum of 100 connections will be accepted between accept() calls.
|
/// A maximum of 100 connections will be accepted between accept() calls.
|
||||||
|
|
|
@ -68,7 +68,9 @@ namespace Socket{
|
||||||
class Server{
|
class Server{
|
||||||
private:
|
private:
|
||||||
int sock; ///< Internally saved socket number.
|
int sock; ///< Internally saved socket number.
|
||||||
public:
|
bool IPv6bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv6 socket
|
||||||
|
bool IPv4bind(int port, std::string hostname, bool nonblock); ///< Attempt to bind an IPv4 socket
|
||||||
|
public:
|
||||||
Server(); ///< Create a new base Server.
|
Server(); ///< Create a new base Server.
|
||||||
Server(int port, std::string hostname = "0.0.0.0", bool nonblock = false); ///< Create a new TCP Server.
|
Server(int port, std::string hostname = "0.0.0.0", bool nonblock = false); ///< Create a new TCP Server.
|
||||||
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
Server(std::string adres, bool nonblock = false); ///< Create a new Unix Server.
|
||||||
|
|
Loading…
Add table
Reference in a new issue