IZ_INT Udp::wait( IZ_UINT sec/*= 0*/, IZ_UINT usec/*= 0*/) { IZ_ASSERT(isValidSocket(m_socket)); timeval t_val = { sec, usec }; timeval* pTval = nullptr; if (sec > 0 || usec > 0) { pTval = &t_val; } fd_set readFD; fd_set exceptionFD; FD_ZERO(&readFD); FD_ZERO(&exceptionFD); FD_SET(m_socket, &readFD); FD_SET(m_socket, &exceptionFD); // ファイルディスクリプタ(ソケット)の状態遷移待ち auto resSelect = select( //FD_SETSIZE, 0, &readFD, NULL, &exceptionFD, pTval); if (resSelect <= 0) { return 0; } // 受信. if (FD_ISSET(m_socket, &readFD)) { return 1; } if (FD_ISSET(m_socket, &exceptionFD)) { // TODO IZ_ASSERT(IZ_FALSE); return -1; } return 0; }
// 起動. IZ_BOOL Udp::start() { if (isValidSocket(m_socket)) { return IZ_TRUE; } IZ_BOOL result = IZ_FALSE; // ソケットの生成 m_socket = socket( AF_INET, // アドレスファミリ SOCK_DGRAM, // ソケットタイプ IPPROTO_UDP); // プロトコル result = isValidSocket(m_socket); if (!result) { IZ_ASSERT(IZ_FALSE); stop(); } return result; }
bool Socket::shutdown() { if (!isValidSocket()) { return false; } S32 retCode = ::shutdown(sObj, SD_SEND); if (retCode == SOCKET_ERROR) { cout << "Socket::shutdown(): Failed to shut down socket: " << WSAGetLastError() << endl; ::closesocket(sObj); sObj = INVALID_SOCKET; WSACleanup(); return false; } onSelfDisconnect(); return true; }
SocketCode Socket::connect(UFC32 host, const U32 port) { if (!isValidSocket()) { return InvalidSocket; } struct hostent *he; if ((he = gethostbyname(host)) == NULL) { cout << "Socket::connect(): Failed to convert " << host << " to an IP" << endl; } _mAddr.sin_family = AF_INET; _mAddr.sin_port = htons(port); memcpy(&_mAddr.sin_addr, he->h_addr_list[0], he->h_length); S32 status = ::connect(sObj, (sockaddr *)&_mAddr, sizeof(_mAddr)); if (status == 0) { onConnected(); return Connected; } cout << "Socket::connect(): Failed to connect: " << status << ", errno " << errno << endl; onConnectFailed(); return ConnectionFailed; }
// 指定した接続先にデータを送信. IZ_INT Udp::sendTo( const void* data, IZ_UINT size, IPv4Endpoint& remoteEp) { IZ_ASSERT(isValidSocket(m_socket)); VRETURN_VAL(remoteEp != m_host, 0); sockaddr_in addr; remoteEp.get(addr); IZ_INT ret = sendto( m_socket, (const char*)data, size, 0, (sockaddr*)&addr, sizeof(addr)); return ret; }
bool Socket_TCP::connectTo(const char * hostname, uint16_t port, uint32_t timeout) { char servport[32]; int rc; struct in6_addr serveraddr; struct addrinfo hints, *res=NULL; memset(&hints, 0x00, sizeof(hints)); #ifdef _WIN32 hints.ai_flags = 0; #else hints.ai_flags = AI_NUMERICSERV; #endif hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; rc = inet_pton(AF_INET, hostname, &serveraddr); if (rc == 1) { hints.ai_family = AF_INET; hints.ai_flags |= AI_NUMERICHOST; } else { rc = inet_pton(AF_INET6, hostname, &serveraddr); if (rc == 1) { hints.ai_family = AF_INET6; hints.ai_flags |= AI_NUMERICHOST; } } snprintf(servport,32,"%u",port); rc = getaddrinfo(hostname, servport, &hints, &res); if (rc != 0) { // Host not found. lastError = "Error resolving hostname"; return false; } bool connected = false; for (struct addrinfo *resiter=res; resiter && !connected; resiter = resiter->ai_next) { if (getSocket() >=0 ) closeSocket(); setSocket(socket(res->ai_family, res->ai_socktype, res->ai_protocol)); if (!isValidSocket()) { lastError = "socket() failed"; break; } // Set the read timeout here. (to zero) setReadTimeout(0); if (internalConnect(getSocket(),resiter->ai_addr, resiter->ai_addrlen,timeout)) { // now it's connected... if (PostConnectSubInitialization()) { connected = true; } else { // should disconnect here. shutdownSocket(); // drop the socket descriptor. we don't need it anymore. closeSocket(); } break; } else { // drop the current socket... (and free the resource :)) shutdownSocket(); closeSocket(); } } freeaddrinfo(res); if (!connected) { lastError = "connect() failed"; return false; } return true; }
bool Socket_TCP::listenOn(uint16_t port, const char * listenOnAddr, bool useIPv4, int recvbuffer,unsigned int backlog) { int on=1; if (useIPv4) { setSocket(socket(AF_INET, SOCK_STREAM, 0)); if (!isValidSocket()) { lastError = "socket() failed"; return false; } } else { setSocket(socket(AF_INET6, SOCK_STREAM, 0)); if (!isValidSocket()) { lastError = "socket() failed"; return false; } } if (recvbuffer) setRecvBuffer(recvbuffer); if (setsockopt(getSocket(), SOL_SOCKET, SO_REUSEADDR, (char *)&on,sizeof(on)) < 0) { lastError = "setsockopt(SO_REUSEADDR) failed"; closeSocket(); return false; } if (useIPv4) { struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(port); inet_pton(AF_INET, listenOnAddr, &serveraddr.sin_addr); if (bind(getSocket(),(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0) { lastError = "bind() failed"; closeSocket(); return false; } } else { struct sockaddr_in6 serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin6_family = AF_INET6; serveraddr.sin6_port = htons(port); inet_pton(AF_INET6, listenOnAddr, &serveraddr.sin6_addr); if (bind(getSocket(),(struct sockaddr *)&serveraddr,sizeof(serveraddr)) < 0) { lastError = "bind() failed"; closeSocket(); return false; } } if (listen(getSocket(), backlog) < 0) { lastError = "listen() failed"; closeSocket(); return false; } return true; }