/*! \internal Sets the port and address to a sockaddr. Requires that sa point to the IPv6 struct if the address is IPv6. */ static inline void qt_socket_setPortAndAddress(SOCKET socketDescriptor, sockaddr_in * sockAddrIPv4, qt_sockaddr_in6 * sockAddrIPv6, quint16 port, const QHostAddress & address, sockaddr ** sockAddrPtr, QT_SOCKLEN_T *sockAddrSize) { #if !defined(QT_NO_IPV6) if (address.protocol() == QAbstractSocket::IPv6Protocol) { memset(sockAddrIPv6, 0, sizeof(qt_sockaddr_in6)); sockAddrIPv6->sin6_family = AF_INET6; sockAddrIPv6->sin6_scope_id = address.scopeId().toInt(); WSAHtons(socketDescriptor, port, &(sockAddrIPv6->sin6_port)); Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&(sockAddrIPv6->sin6_addr.qt_s6_addr), &tmp, sizeof(tmp)); *sockAddrSize = sizeof(qt_sockaddr_in6); *sockAddrPtr = (struct sockaddr *) sockAddrIPv6; } else #endif if (address.protocol() == QAbstractSocket::IPv4Protocol || address.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) { memset(sockAddrIPv4, 0, sizeof(sockaddr_in)); sockAddrIPv4->sin_family = AF_INET; WSAHtons(socketDescriptor, port, &(sockAddrIPv4->sin_port)); WSAHtonl(socketDescriptor, address.toIPv4Address(), &(sockAddrIPv4->sin_addr.s_addr)); *sockAddrSize = sizeof(sockaddr_in); *sockAddrPtr = (struct sockaddr *) sockAddrIPv4; } else { // unreachable } }
GSocketUdpServer::GSocketUdpServer(unsigned int port, unsigned int maxConnexion) { this->_port = port; this->_maxConnexion = maxConnexion; #if defined (GWIN) WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { GWarning::Warning("GSocketUdpServer", "GSocketUdpServer(unsigned int port, unsigned int max)", "Error WSAStartup()"); throw GException("GSocketUdpServer", "Error WSAStartup() !"); } this->_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0); if (this->_socket == INVALID_SOCKET) { GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSASocket()"); throw GException("GSocketUdpServer", "Error WSASocket()"); } this->_sockaddr.sin_family = AF_INET; this->_sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (WSAHtons(this->_socket, this->_port, &this->_sockaddr.sin_port) == SOCKET_ERROR) { GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSAHtons()"); throw GException("GSocketUdpServer", "Error WSAHtons()"); } if (WSAHtonl(this->_socket, INADDR_ANY, &this->_sockaddr.sin_addr.s_addr) == SOCKET_ERROR) { GWarning::Warning("GSocketTcpServer", "GSocketTcpServer(unsigned int port, unsigned int max)", "Error WSAHtons()"); throw GException("GSocketTcpServer", "Error in WSAHtonl()"); } sockaddr_in s_port; socklen_t len = sizeof(s_port); if (bind(this->_socket, reinterpret_cast <sockaddr*> (&this->_sockaddr), sizeof(this->_sockaddr)) == SOCKET_ERROR) { closesocket(this->_socket); throw GException("GSocketTcpServer", "bind() failed."); } if (getsockname(this->_socket, (SOCKADDR*)&s_port, &len) < 0) { closesocket(this->_socket); throw GException("GSocketTcpServer", "Error sockname"); } #else if ((int)(this->_socket = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { this->_lastError = GSocketUdpServer::ERROR_SOCKET; throw GException("GSocketUdpServer", "Error socket()"); } this->_sockaddr.sin_family = AF_INET; this->_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); this->_sockaddr.sin_port = htons(this->_port); if (bind(this->_socket,(sockaddr *) &(this->_sockaddr), sizeof (this->_sockaddr)) == SOCKET_ERROR) { this->_lastError = GSocketTcpServer::ERROR_SOCKET; throw GException("GSocketTcpServer", "Error bind"); } #endif }
void SocketUdp::Bind(const EndPoint& ep) { SOCKADDR_IN sin; if (!ep.getIp()) WSAHtonl(this->socket_, INADDR_ANY, &sin.sin_addr.s_addr); else sin.sin_addr.s_addr = inet_addr(ep.getIpStr().c_str()); sin.sin_family = AF_INET; WSAHtons(this->socket_, ep.getPort(), &sin.sin_port); if ((bind(this->socket_, reinterpret_cast<SOCKADDR*>(&sin), sizeof sin)) == SOCKET_ERROR) throw ErrorInit("Cannot bind the socket"); }
/*! Listen a port with SO_REUSEADDR option. This function must be called in a tfserver process. */ int TApplicationServer::nativeListen(const QHostAddress &address, quint16 port, OpenFlag) { int protocol = (address.protocol() == QAbstractSocket::IPv6Protocol) ? AF_INET6 : AF_INET; SOCKET sock = ::WSASocket(protocol, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); if (sock == INVALID_SOCKET) { tSystemError("WSASocket Error: %d", WSAGetLastError()); return -1; } // ReuseAddr bool on = true; if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) { tSystemError("setsockopt error: %d", WSAGetLastError()); goto error_socket; } if (address.protocol() == QAbstractSocket::IPv6Protocol) { struct tf_in6_addr { quint8 tf_s6_addr[16]; }; struct tf_sockaddr_in6 { short sin6_family; /* AF_INET6 */ quint16 sin6_port; /* Transport level port number */ quint32 sin6_flowinfo; /* IPv6 flow information */ struct tf_in6_addr sin6_addr; /* IPv6 address */ quint32 sin6_scope_id; /* set of interfaces for a scope */ } sa6; memset(&sa6, 0, sizeof(sa6)); sa6.sin6_family = AF_INET6; WSAHtons(sock, port, &(sa6.sin6_port)); Q_IPV6ADDR ipv6 = address.toIPv6Address(); memcpy(&(sa6.sin6_addr.tf_s6_addr), &ipv6, sizeof(ipv6)); if (::bind(sock, (struct sockaddr *)&sa6, sizeof(sa6)) != 0) { tSystemError("bind(v6) error: %d", WSAGetLastError()); goto error_socket; } } else if (address.protocol() == QAbstractSocket::IPv4Protocol #if QT_VERSION >= 0x050000 || address.protocol() == QAbstractSocket::QAbstractSocket::AnyIPProtocol #endif ) { struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; WSAHtons(sock, port, &(sa.sin_port)); WSAHtonl(sock, address.toIPv4Address(), &(sa.sin_addr.s_addr)); if (::bind(sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) { tSystemError("bind error: %d", WSAGetLastError()); goto error_socket; } } else { // UnknownNetworkLayerProtocol goto error_socket; } if (::listen(sock, 50) != 0) { tSystemError("listen error: %d", WSAGetLastError()); goto error_socket; } return sock; error_socket: nativeClose(sock); return -1; }