SXSocketRef SXCreateClientSocket(const char * ipaddr, unsigned short port, int domain, int type, int protocol, SXError * err_ret) { SXSocketRef sockPtr = (SXSocketRef)sx_calloc(1, sizeof(sx_socket_t)); if (sockPtr == NULL) ERR_RET(SX_ERROR_MEM_ALLOC); sockPtr->protocol = protocol; sockPtr->type = type; sockPtr->domain = domain; sx_obj_init(&sockPtr->obj, &SXFreeSocket); socklen_t addrlen; memset(&sockPtr->addr, 0, sizeof(struct sockaddr_storage)); if ((sockPtr->sockfd = socket(domain, type, protocol)) == -1) { perror("socket"); ERR_RET(SX_ERROR_SYS_SOCKET); } switch (domain) { case AF_INET: sockaddr_in(sockPtr->addr).sin_port = htons(port); sockaddr_in(sockPtr->addr).sin_len = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in); inet_pton(AF_INET, ipaddr, &sockaddr_in(sockPtr->addr).sin_addr); break; case AF_INET6: sockaddr_in6(sockPtr->addr).sin6_port = htons(port); sockaddr_in6(sockPtr->addr).sin6_len = sizeof(struct sockaddr_in6); addrlen = sizeof(struct sockaddr_in6); inet_pton(AF_INET6, ipaddr, &sockaddr_in6(sockPtr->addr).sin6_addr); break; default: ERR_RET(SX_ERROR_INVALID_IPADDR); return NULL; } int yes = 1; if (setsockopt(sockPtr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &yes, sizeof(int)) == -1) { perror("setsockopt"); ERR_RET(SX_ERROR_SYS_SETSOCKOPT); } sockPtr->addr.ss_family = domain; ERR_RET(SX_SUCCESS); return sockPtr; }
SXError dns_lookup(SXSocketRef socket, const char * hostname, const char * service, struct addrinfo * hint) { struct addrinfo * info, * cinfo; if (getaddrinfo(hostname, service, hint, &info) != 0) return SX_ERROR_SYS_GET_ADDR_INFO; cinfo = info; while (cinfo != NULL) { cinfo = cinfo->ai_next; short port = htons(getservbyname(service, NULL)->s_port); memset(&socket->addr, 0, sizeof(struct sockaddr_storage)); switch (cinfo->ai_family) { case AF_INET: socket->domain = AF_INET; socket->type = cinfo->ai_socktype; socket->protocol = cinfo->ai_protocol; sockaddr_in(socket->addr).sin_len = sizeof(struct sockaddr_in); sockaddr_in(socket->addr).sin_family = AF_INET; sockaddr_in(socket->addr).sin_addr = sockaddr_in(cinfo->ai_addr).sin_addr; sockaddr_in(socket->addr).sin_port = port; goto clean; case AF_INET6: sockaddr_in6(socket->addr).sin6_len = sizeof(struct sockaddr_in6); sockaddr_in6(socket->addr).sin6_family = AF_INET6; sockaddr_in6(socket->addr).sin6_port = port; sockaddr_in6(socket->addr).sin6_addr = sockaddr_in6(cinfo->ai_addr).sin6_addr; goto clean; default: goto cont; } cont: continue; } clean: freeaddrinfo(info); return SX_SUCCESS; }
bool Accept(TcpSocket& connection, bool blocking = true) const { if (!IsListening()) { throw std::runtime_error("TcpSocket.Accept - Called on a socket that does not have listening mode enabled"); } auto newSocket = SOCKET(0); auto address = sockaddr_in(); auto tryAgain = bool(); do { tryAgain = false; if (!Winsock::Accept(socket, address, newSocket)) { switch (WSAGetLastError()) { case WSAEWOULDBLOCK: //if (!IsBlocking()) //{ // throw std::runtime_error("TcpSocket.Accept - Received would-block error for non-blocking socket"); //} return false; case WSAECONNRESET: tryAgain = true; break; default: return false; } } } while (tryAgain); if (connection.IsOpen()) { connection.Close(); } connection.socket = newSocket; connection.isListening = false; if (!Winsock::IoctlSocket(connection.socket, blocking)) { throw std::runtime_error("TcpSocket.Accept - Unable to set blocking mode on new connection"); } connection.isBlocking = blocking; return true; }
sockaddr_in fillAddr (const std::string &address, const unsigned short port) { sockaddr_in retv = sockaddr_in(); retv.sin_family = AF_INET; hostent *host; // Resolve name if ((host = gethostbyname(address.c_str())) == NULL) { // TODO throw exception } retv.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]); retv.sin_port = htons(port); // Assign port in network byte order return retv; }
SXSocketRef SXCreateServerSocket(unsigned short port, int domain, int type, int protocol, SXError * err_ret) { SXSocketRef sockPtr = (SXSocketRef)sx_calloc(1, sizeof(sx_socket_t)); if (sockPtr == NULL) ERR_RET(SX_ERROR_MEM_ALLOC); sockPtr->domain = domain; sockPtr->type = type; sockPtr->protocol = protocol; sockPtr->ref_count = 1; sockPtr->port = port; socklen_t addrlen; memset(&sockPtr->addr, 0, sizeof(struct sockaddr_storage)); if ((sockPtr->sockfd = socket(domain, type, protocol)) == -1) { perror("socket"); ERR_RET(SX_ERROR_SYS_SOCKET); } switch (domain) { case AF_INET: sockaddr_in(sockPtr->addr).sin_addr.s_addr = INADDR_ANY; sockaddr_in(sockPtr->addr).sin_port = htons(port); sockaddr_in(sockPtr->addr).sin_len = sizeof(struct sockaddr_in); addrlen = sizeof(struct sockaddr_in); break; case AF_INET6: sockaddr_in6(sockPtr->addr).sin6_addr = in6addr_any; sockaddr_in6(sockPtr->addr).sin6_port = htons(port); sockaddr_in6(sockPtr->addr).sin6_len = sizeof(struct sockaddr_in6); addrlen = sizeof(struct sockaddr_in6); break; default: ERR_RET(SX_ERROR_INVALID_IPADDR); return NULL; } sockPtr->addr.ss_family = domain; int yes=1; if (setsockopt(sockPtr->sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { perror("setsockopt"); ERR_RET(SX_ERROR_SYS_SETSOCKOPT); } if (bind(sockPtr->sockfd, (struct sockaddr *)&sockPtr->addr, addrlen) == -1) { perror("bind"); ERR_RET(SX_ERROR_SYS_BIND); } ERR_RET(SX_SUCCESS); return sockPtr; }
// ¬ Ћё„≈Ќ»я. #include "NClient.h" // »Ќ»÷»јЋ»«ј÷»я —“ј“»„≈— »’ ѕ≈–≈ћ≈ЌЌџ’. WSADATA NClient::wsadata = WSADATA(); sockaddr_in NClient::ssin = sockaddr_in(); sockaddr_in NClient::SocketAddress = sockaddr_in(); SOCKET NClient::p_Socket = NULL; int NClient::iResult = 0, NClient::iSended = 0; // ‘”Ќ ÷»» Ћј——ќ¬. //== ласс клиента. //== —тарт клиента. bool NClient::Start() { WSAStartup(MAKEWORD(2, 2), &wsadata); p_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (p_Socket == SOCKET_ERROR) { printf("!! Error when creating socket.\n"); WSACleanup(); return false; } ssin.sin_family = AF_INET; ssin.sin_addr.s_addr = inet_addr("127.0.0.1"); ssin.sin_port = htons(SRV_PORT); printf("Client is running.\n");