/* * Client socket class * * Encapsulates a socket for ease of use. * * Copyright (C) 2008 Alejandro Valenzuela Roca, * * http://mexinetica.com/~lanjoe9 * * This file is part of MotorJ, a free framework for videogame development. * * * * MotorJ is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MotorJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MotorJ. If not, see . */ #include "clientsocket-class.h" #ifdef NINTENDO_DS #include #include #define socklen_t int #endif mjClientSocket::mjClientSocket(MJCLIENTSOCKETTYPE type, unsigned port) { #ifdef NINTENDO_DS int iioctlparameter = 1; #else int isetsockparameter = 1; #endif switch(type) { case CS_IPV4TCP: commSocket = socket(PF_INET, SOCK_STREAM, 0); s_to.sin_family = AF_INET; break; case CS_IPV4UDP: commSocket = socket(PF_INET, SOCK_DGRAM, 0); s_to.sin_family = AF_INET; break; case CS_IPV6TCP: commSocket = socket(PF_INET6, SOCK_STREAM, 0); s_to.sin_family = AF_INET6; break; case CS_IPV6UDP: commSocket = socket(PF_INET6, SOCK_DGRAM, 0); s_to.sin_family = AF_INET6; break; } // The socket will be non-blocking by default, due to the non-threaded // nature of the Nintendo DS.. #ifdef NINTENDO_DS ioctl(commSocket,FIONBIO,&iioctlparameter); s_me.sin_addr.s_addr = Wifi_GetIP(); #else fcntl(commSocket, F_SETFD, O_NONBLOCK); setsockopt(commSocket, SOL_SOCKET, SO_BROADCAST, &isetsockparameter, sizeof(isetsockparameter)); #endif s_me.sin_family = s_to.sin_family; s_me.sin_port = s_to.sin_port = htons(port); iport = port; itype = type; } mjClientSocket::~mjClientSocket() { DoDisconnect (); } // In case you had forgotten what the socket was created for.. unsigned mjClientSocket::GetPort() { return iport; } MJCLIENTSOCKETTYPE mjClientSocket::GetType() { return itype; } short mjClientSocket::DoConnect(char * address) { struct hostent * target = gethostbyname(address); struct sockaddr_in s_udp_tmp; iconnected = false; if (target) { s_to.sin_addr.s_addr = *( (unsigned long *)(target->h_addr_list[0]) ); } else return -1; if ((itype == CS_IPV4UDP) || (itype == CS_IPV6UDP)) { s_udp_tmp.sin_family = s_me.sin_family; s_udp_tmp.sin_port = s_to.sin_port; s_udp_tmp.sin_addr.s_addr = INADDR_ANY; bind(commSocket, (struct sockaddr *) &s_udp_tmp, sizeof(s_udp_tmp)); iconnected = true; return 0; } #ifdef NINTENDO_WII else if (connect(commSocket, (sockaddr *) &s_to, sizeof(s_to)) == 0) #else else if (connect(commSocket, (const sockaddr *) &s_to, sizeof(s_to)) == 0) #endif { iconnected = true; s_from.sin_addr.s_addr = s_to.sin_addr.s_addr; return 0; } else { return -2; } } char * mjClientSocket::Who_str() { return inet_ntoa(s_from.sin_addr); } unsigned long mjClientSocket::Who() { return (unsigned long) s_from.sin_addr.s_addr; } bool mjClientSocket::IsConnected() { return iconnected; } void mjClientSocket::DoDisconnect() { if ((itype == CS_IPV4TCP) || (itype == CS_IPV6TCP)) { shutdown(commSocket, SHUT_RDWR); } else { close(commSocket); } iconnected = false; } int mjClientSocket::SendData(void * data, unsigned length) { if (iconnected) { switch (itype) { case CS_IPV4TCP: case CS_IPV6TCP: return send(commSocket, data, length, 0); break; case CS_IPV4UDP: case CS_IPV6UDP: return sendto(commSocket, data, length, 0, (struct sockaddr *) &s_to, sizeof(s_to)); break; } } return -1; } int mjClientSocket::RecvData(void * data, unsigned maxlength) { int tmplen; int bytesReceived = 0; if (iconnected) { switch(itype) { case CS_IPV4TCP: case CS_IPV6TCP: bytesReceived = recv(commSocket, data, maxlength, 0); if (! bytesReceived) { iconnected = 0; } else if (bytesReceived < 0) // <<<- E_WOULDBLOCK { return -1; } break; case CS_IPV4UDP: case CS_IPV6UDP: bytesReceived = recvfrom(commSocket, data, maxlength, 0, (struct sockaddr * ) &s_from, (socklen_t *) &tmplen); if (!bytesReceived) // <<<- E_WOULDBLOCK return -1; break; } return bytesReceived; } return -1; } char * mjClientSocket::GetOwnIP_str() { return inet_ntoa(s_me.sin_addr); } unsigned long mjClientSocket::GetOwnIP() { return s_me.sin_addr.s_addr; }