#ifndef RC_NET_H_INCLUDED #define RC_NET_H_INCLUDED #include "rc_os_defines.h" #ifdef RC_ANDROID #define RC_MOBILE #endif #ifdef RC_IOS #define RC_MOBILE #endif #ifdef RC_ANDROID #include //Using SDL and standard IO #include "SDL.h" #include #include #include #include #include "SDL_net.h" #include #include #else #ifdef RC_IOS //Using SDL and standard IO #include "SDL2/SDL.h" #include #include #include #include #include #include "SDL2/SDL_net.h" #else //Using SDL and standard IO #include #include #include #include #include #include #include #include #include #endif //RC_IOS #endif // RC_ANDROID const int MAX_SOCKETS = 256; struct rc_tcp_socket_obj { TCPsocket socket; bool active = false; }; std::vector rc_tcp_socket; struct rc_udp_socket_obj { UDPsocket socket; bool active = false; }; std::vector rc_udp_socket; UDPpacket * rc_udp_packet; int rc_udp_channel; std::string rc_udp_data; int rc_udp_len; int rc_udp_maxlen; std::string rc_udp_host; Uint16 rc_udp_port; int rc_packet_size = 0; SDLNet_SocketSet rc_socket_set; bool rc_net_init() { if (SDLNet_Init() < 0) { fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); //exit(EXIT_FAILURE); return false; } rc_socket_set = SDLNet_AllocSocketSet(MAX_SOCKETS*2); rc_udp_packet = SDLNet_AllocPacket(512); rc_packet_size = 512; return true; } void rc_net_quit() { if(rc_socket_set) { SDLNet_FreeSocketSet(rc_socket_set); rc_socket_set = NULL; } SDLNet_Quit(); } int rc_net_tcp_openSocket(std::string host, Uint16 port) { int id = -1; for(int i = 0; i < rc_tcp_socket.size(); i++) { if(!rc_tcp_socket[i].active) { id = i; break; } } if(id < 0) { rc_tcp_socket_obj obj; id = rc_tcp_socket.size(); rc_tcp_socket.push_back(obj); } IPaddress ip; if(host.compare("") == 0) { //exit(0); SDLNet_ResolveHost(&ip, NULL, port); } else { //exit(0); SDLNet_ResolveHost(&ip, host.c_str(), port); } rc_tcp_socket[id].socket = SDLNet_TCP_Open(&ip); if(!rc_tcp_socket[id].socket) return -1; rc_tcp_socket[id].active = true; //cout << "Add socket to socket_set" << endl; SDLNet_TCP_AddSocket(rc_socket_set, rc_tcp_socket[id].socket); return id; } void rc_net_tcp_closeSocket(int _socket) { if(_socket < 0 || _socket >= rc_tcp_socket.size()) return; if(rc_tcp_socket[_socket].socket == NULL) { rc_tcp_socket[_socket].active = false; return; } SDLNet_TCP_DelSocket(rc_socket_set, rc_tcp_socket[_socket].socket); SDLNet_TCP_Close(rc_tcp_socket[_socket].socket); rc_tcp_socket[_socket].socket = NULL; rc_tcp_socket[_socket].active = false; } double rc_net_tcp_remoteHost(int _socket) { if(_socket < 0 || _socket >= rc_tcp_socket.size()) return -1; if(rc_tcp_socket[_socket].socket == NULL) return -1; IPaddress * ip = SDLNet_TCP_GetPeerAddress(rc_tcp_socket[_socket].socket); return (double)ip->host; } double rc_net_tcp_remotePort(int _socket) { if(_socket < 0 || _socket >= rc_tcp_socket.size()) return -1; if(rc_tcp_socket[_socket].socket == NULL) return -1; IPaddress * ip = SDLNet_TCP_GetPeerAddress(rc_tcp_socket[_socket].socket); return (double)ip->port; } int rc_net_checkSockets(Uint32 m) { return SDLNet_CheckSockets(rc_socket_set, m); } int rc_net_tcp_socketReady(int _socket) { if(_socket < 0 || _socket >= rc_tcp_socket.size()) return 0; if(rc_tcp_socket[_socket].socket == NULL) return 0; return SDLNet_SocketReady(rc_tcp_socket[_socket].socket); } int rc_net_tcp_getData(int socket, int numBytes, void * dst) { if(socket < 0 || socket >= rc_tcp_socket.size()) return 0; int rtn = SDLNet_TCP_Recv(rc_tcp_socket[socket].socket, dst, numBytes); return rtn; } int rc_net_tcp_getData_str(int socket, int numBytes, std::string * dst) { char c[numBytes+1]; int rtn = rc_net_tcp_getData(socket, numBytes, c); c[numBytes] = '\0'; //cout << "Read bytes: " << (string)c << endl; dst[0] = c; return rtn; } int rc_net_tcp_getData_dbl(int socket, int numBytes, double * dst) { int i[numBytes]; int rtn = rc_net_tcp_getData(socket, numBytes, i); for(int n = 0; n < numBytes; n++) { dst[n] = i[n]; } return rtn; } void rc_net_tcp_sendData(int socket, std::string data) { if(socket < 0 || socket >= rc_tcp_socket.size()) return; SDLNet_TCP_Send(rc_tcp_socket[socket].socket, data.c_str(), data.length()); } int rc_net_tcp_acceptSocket(int socket_server) { if(socket_server < 0 || socket_server >= rc_tcp_socket.size()) return -1; int socket_client = -1; for(int i = 0; i < rc_tcp_socket.size(); i++) { if(!rc_tcp_socket[i].active) { socket_client = i; break; } } if(socket_client < 0) { rc_tcp_socket_obj obj; socket_client = rc_tcp_socket.size(); rc_tcp_socket.push_back(obj); } //cout << "\n\nthis is a test\n\n"; if(rc_tcp_socket[socket_server].socket == NULL) { //cout << "no server" << endl; return -1; } bool val = (rc_tcp_socket[socket_client].socket = SDLNet_TCP_Accept(rc_tcp_socket[socket_server].socket)); if(val) SDLNet_TCP_AddSocket(rc_socket_set, rc_tcp_socket[socket_client].socket); else { rc_tcp_socket[socket_client].socket = NULL; rc_tcp_socket[socket_client].active = false; return -1; } //cout << "cp1\n"; return socket_client; } bool rc_net_udp_openSocket(Uint16 port) { int socket = -1; for(int i = 0; i < rc_udp_socket.size(); i++) { if(!rc_udp_socket[i].active) { socket = i; break; } } if(socket < 0) { rc_udp_socket_obj obj; socket = rc_udp_socket.size(); rc_udp_socket.push_back(obj); } bool rtn = (bool)(rc_udp_socket[socket].socket = SDLNet_UDP_Open(port)); if(rtn) { SDLNet_UDP_AddSocket(rc_socket_set, rc_udp_socket[socket].socket); rc_udp_socket[socket].active = true; } else { rc_udp_socket[socket].active = false; rc_udp_socket[socket].socket = NULL; return -1; } return socket; } int rc_net_udp_socketReady(int socket) { if(socket < 0 || socket >= rc_udp_socket.size()) return 0; return SDLNet_SocketReady(rc_udp_socket[socket].socket); } int rc_net_udp_readStream(int socket, std::string * host, double * port, std::string * dst) { if(socket < 0 || socket >= rc_udp_socket.size()) { rc_udp_channel = 0; *dst = ""; rc_udp_len = 0; rc_udp_maxlen = rc_udp_packet->maxlen; *host = SDLNet_ResolveIP(&rc_udp_packet->address); *port = rc_udp_packet->address.port; return 0; } //cout << "DEBUG READSTREAM\n"; //UDPsocket sd; /* Socket descriptor */ //UDPpacket *p; /* Pointer to packet memory */ //int quit = 0; /* Make space for the packet */ //if (!(rc_udp_packet = SDLNet_AllocPacket(512))) //{ // fprintf(stderr, "SDLNet_AllocPacket: %s\n", SDLNet_GetError()); // exit(EXIT_FAILURE); //} /* Main loop */ /* Wait a packet. UDP_Recv returns != 0 if a packet is coming */ //while(!quit) //{ if (SDLNet_UDP_Recv(rc_udp_socket[socket].socket, rc_udp_packet)) { //printf("UDP Packet incoming\n"); //printf("\tChan: %d\n", rc_udp_packet->channel); rc_udp_channel = rc_udp_packet->channel; //printf("\tData: %s\n", (char *)rc_udp_packet->data); const char * c = (const char *)rc_udp_packet->data; //rc_udp_data = (string)c; *dst = (std::string)c; //printf("\tLen: %d\n", rc_udp_packet->len); rc_udp_len = rc_udp_packet->len; //printf("\tMaxlen: %d\n", rc_udp_packet->maxlen); rc_udp_maxlen = rc_udp_packet->maxlen; //printf("\tStatus: %d\n", rc_udp_packet->status); //printf("\tAddress: %x %x\n", rc_udp_packet->address.host, rc_udp_packet->address.port); //rc_udp_host = SDLNet_ResolveIP(&rc_udp_packet->address); *host = SDLNet_ResolveIP(&rc_udp_packet->address); //rc_udp_port = rc_udp_packet->address.port; *port = rc_udp_packet->address.port; return 1; //quit = 1; } else { rc_udp_channel = 0; //rc_udp_data = ""; *dst = ""; rc_udp_len = 0; rc_udp_maxlen = rc_udp_packet->maxlen; //rc_udp_host = SDLNet_ResolveIP(&rc_udp_packet->address); *host = SDLNet_ResolveIP(&rc_udp_packet->address); //rc_udp_port = rc_udp_packet->address.port; *port = rc_udp_packet->address.port; return 0; } //} //SDLNet_FreePacket(rc_udp_packet); } Uint32 rc_net_udp_len() { return rc_udp_len; } Uint32 rc_net_udp_maxlen() { return rc_udp_maxlen; } std::string rc_net_udp_getRemoteHost(int socket) { if(socket < 0 || socket >= rc_udp_socket.size()) return ""; if(!rc_udp_socket[socket].active) return ""; IPaddress * ip = SDLNet_UDP_GetPeerAddress(rc_udp_socket[socket].socket,0); // return SDLNet_ResolveIP(ip); } double rc_net_udp_getRemotePort(int socket) { if(socket < 0 || socket >= rc_udp_socket.size()) return -1; if(!rc_udp_socket[socket].active) return -1; IPaddress * ip = SDLNet_UDP_GetPeerAddress(rc_udp_socket[socket].socket,0); return (double)ip->port; } void rc_net_udp_closeSocket(int socket) { if(socket < 0 || socket >= rc_udp_socket.size()) return; if(!rc_udp_socket[socket].active) { rc_udp_socket[socket].socket = NULL; return; } SDLNet_UDP_DelSocket(rc_socket_set, rc_udp_socket[socket].socket); SDLNet_UDP_Close(rc_udp_socket[socket].socket); rc_udp_socket[socket].socket = NULL; rc_udp_socket[socket].active = false; } int rc_net_udp_sendData(int slot, std::string host, Uint16 port, std::string s_data) { if(socket < 0 || socket >= rc_udp_socket.size()) return 0; IPaddress srvadd; if(s_data.length()+1 > rc_packet_size) { rc_packet_size = SDLNet_ResizePacket(rc_udp_packet, s_data.length()+1); if(rc_packet_size < s_data.length()) { std::cout << "UDP_SendData Error: " << SDLNet_GetError() << endl; return 0; } } if(rc_udp_packet == NULL) return 0; if (SDLNet_ResolveHost(&srvadd, host.c_str(), port) == -1) { std::cout << "UDP_SendData Error: " << SDLNet_GetError() << "\n"; //exit(EXIT_FAILURE); return 0; } rc_udp_packet->address.host = srvadd.host; rc_udp_packet->address.port = srvadd.port; rc_udp_packet->data = (Uint8*)s_data.c_str(); rc_udp_packet->len = s_data.length()+1; //cout << "#Data = " << (char*)rc_udp_packet->data << endl; //cout << "#Length = " << rc_udp_packet->len << endl; SDLNet_UDP_Send(rc_udp_socket[slot].socket, -1, rc_udp_packet); return 1; } std::string rc_byteToString(Uint8 n) { std::stringstream s; s << (Uint32)n; return s.str(); } std::string rc_net_myLocalIP() { //cout << "MYLOCALIP" << endl; IPaddress myIP; myIP.host = 0; myIP.port = 0; std::string net_name = SDLNet_ResolveIP(&myIP); SDLNet_ResolveHost(&myIP,net_name.c_str(),0); std::string ip = ""; ip += rc_byteToString((Uint8)myIP.host) + "."; ip += rc_byteToString((Uint8)(myIP.host >> 8)) + "."; ip += rc_byteToString((Uint8)(myIP.host >> 16)) + "."; ip += rc_byteToString((Uint8)(myIP.host >> 24)); //cout << "vagina: " << myIP.host << endl; return ip; } #endif // RC_NET_H_INCLUDED