connection receive_data(config& cfg, connection connection_num, bandwidth_in_ptr* bandwidth_in) { if(!socket_set) { return 0; } check_error(); if(disconnection_queue.empty() == false) { const network::connection sock = disconnection_queue.front(); disconnection_queue.pop_front(); throw error("",sock); } if(bad_sockets.count(connection_num) || bad_sockets.count(0)) { return 0; } if(sockets.empty()) { return 0; } const int res = SDLNet_CheckSockets(socket_set,0); for(std::set<network::connection>::iterator i = waiting_sockets.begin(); res != 0 && i != waiting_sockets.end(); ) { connection_details& details = get_connection_details(*i); const TCPsocket sock = details.sock; if(SDLNet_SocketReady(sock)) { // See if this socket is still waiting for it to be assigned its remote handle. // If it is, then the first 4 bytes must be the remote handle. if(is_pending_remote_handle(*i)) { union { char data[4] ALIGN_4; } buf; int len = SDLNet_TCP_Recv(sock,&buf,4); if(len != 4) { throw error("Remote host disconnected",*i); } const int remote_handle = SDLNet_Read32(&buf); set_remote_handle(*i,remote_handle); continue; } waiting_sockets.erase(i++); SDLNet_TCP_DelSocket(socket_set,sock); network_worker_pool::receive_data(sock); } else { ++i; } }
void HandleServer(void) { TCPsocket newsock; int which; unsigned char data; newsock = SDLNet_TCP_Accept(servsock); if ( newsock == NULL ) { return; } /* Look for unconnected person slot */ for ( which=0; which<CHAT_MAXPEOPLE; ++which ) { if ( ! people[which].sock ) { break; } } if ( which == CHAT_MAXPEOPLE ) { /* Look for inactive person slot */ for ( which=0; which<CHAT_MAXPEOPLE; ++which ) { if ( people[which].sock && ! people[which].active ) { /* Kick them out.. */ data = CHAT_BYE; SDLNet_TCP_Send(people[which].sock, &data, 1); SDLNet_TCP_DelSocket(socketset, people[which].sock); SDLNet_TCP_Close(people[which].sock); #ifdef DEBUG fprintf(stderr, "Killed inactive socket %d\n", which); #endif break; } } } if ( which == CHAT_MAXPEOPLE ) { /* No more room... */ data = CHAT_BYE; SDLNet_TCP_Send(newsock, &data, 1); SDLNet_TCP_Close(newsock); #ifdef DEBUG fprintf(stderr, "Connection refused -- chat room full\n"); #endif } else { /* Add socket as an inactive person */ people[which].sock = newsock; people[which].peer = *SDLNet_TCP_GetPeerAddress(newsock); SDLNet_TCP_AddSocket(socketset, people[which].sock); #ifdef DEBUG fprintf(stderr, "New inactive socket %d\n", which); #endif } }
void Connection::cleanSet(){ ScopedMutexLock(pimpl_->dataAccess); //remove from set if( pimpl_->group ){ SDLNet_TCP_DelSocket(pimpl_->group, pimpl_->userSocket); } // clean up if( pimpl_->createdSet == 1 ){ SDLNet_FreeSocketSet(pimpl_->group); pimpl_->createdSet = 0; } pimpl_->group = NULL; }
TCPClientSocket::~TCPClientSocket() { if(sendbuffer) delete [] sendbuffer; #ifdef NATIVESOCKETS if(nativetcpstruct) delete [] nativetcpstruct; else #endif if(mysock) { if(listensocketset) SDLNet_TCP_DelSocket(listensocketset,mysock); SDLNet_TCP_Close(mysock); } if(listensocketset) SDLNet_FreeSocketSet(listensocketset); }
bool disconnect(connection s) { if(s == 0) { while(sockets.empty() == false) { assert(sockets.back() != 0); while(disconnect(sockets.back()) == false) { SDL_Delay(1); } } return true; } if (!is_server()) last_ping = 0; const connection_map::iterator info = connections.find(s); if(info != connections.end()) { if (info->second.sock == server_socket) { return true; } if (!network_worker_pool::close_socket(info->second.sock)) { return false; } } bad_sockets.erase(s); std::deque<network::connection>::iterator dqi = std::find(disconnection_queue.begin(),disconnection_queue.end(),s); if(dqi != disconnection_queue.end()) { disconnection_queue.erase(dqi); } const sockets_list::iterator i = std::find(sockets.begin(),sockets.end(),s); if(i != sockets.end()) { sockets.erase(i); const TCPsocket sock = get_socket(s); waiting_sockets.erase(s); SDLNet_TCP_DelSocket(socket_set,sock); SDLNet_TCP_Close(sock); remove_connection(s); } else { if(sockets.size() == 1) { DBG_NW << "valid socket: " << static_cast<int>(*sockets.begin()) << "\n"; } } return true; }
//----------------------------------------------------------------------------- void CloseSocket(int index) { if(sockets[index] == NULL) { fprintf(stderr, "ER: Attempted to delete a NULL socket.\n"); return; } if(SDLNet_TCP_DelSocket(socket_set, sockets[index]) == -1) { fprintf(stderr, "ER: SDLNet_TCP_DelSocket: %s\n", SDLNet_GetError()); exit(-1); } memset(&clients[index], 0x00, sizeof(Client)); SDLNet_TCP_Close(sockets[index]); sockets[index] = NULL; }
int Connection::setSocketSet(const SDLNet_SocketSet& newGroup){ ScopedMutexLock(pimpl_->dataAccess); if( pimpl_->group == newGroup ){ return 1; } //remove from old group if( pimpl_->userSocket && pimpl_->group ){ SDLNet_TCP_DelSocket(pimpl_->group, pimpl_->userSocket); } else { return -1; } //if internal set was used, free it (its no longer needed) if( pimpl_->createdSet ){ SDLNet_FreeSocketSet(pimpl_->group); pimpl_->group = NULL; pimpl_->createdSet = false; } pimpl_->group = newGroup; SDLNet_TCP_AddSocket(pimpl_->group, pimpl_->userSocket); return 1; }
void TCPConnection::Close() { logger->Log( __FILE__, __LINE__, "Closing connection.." ); if ( !isConnected ) { logger->Log( __FILE__, __LINE__, "Can't close : not connected" ); return; } if ( isServer ) { SDLNet_TCP_DelSocket( socketSet, serverSocket ); SDLNet_TCP_Close( serverSocket ); SDLNet_FreeSocketSet( socketSet ); } else { SDLNet_TCP_Close( tcpSocket ); } isConnected = false; }
void remove_socket(struct socket_node *socket) { struct socket_node *p, *prev=NULL; SDLNet_TCP_DelSocket(sockset, socket->sock); SDLNet_TCP_Close(socket->sock); p = socket_list; if (p == socket) { socket_list = socket_list->next; free(p); } else { while (p != NULL && p != socket) { prev = p; p = p->next; } if (p == NULL) do_error("remove_socket()"); /* this shouldn't happen */ if (prev) prev->next = p->next; free(p); } }
void NetServer::broadcastmessage(char * szMsg) { char data[512]; int iLength = strlen(szMsg) + 1; data[0] = NET_MSG_CHAT; data[NET_MSG_CHAT_NLEN] = iLength; memcpy(&data[NET_MSG_CHAT_BODY], szMsg, iLength); for (int k = 0; k < MAXCLIENTS; ++k) { if (clients[k].active) { int iResult = SDLNet_TCP_Send(clients[k].sock, data, iLength + NET_MSG_CHAT_BODY); if(iResult < iLength) { printf("SDLNet_TCP_Send Error: %s\n", SDLNet_GetError()); // It may be good to disconnect sock because it is likely invalid now. SDLNet_TCP_DelSocket(socketset, clients[k].sock); SDLNet_TCP_Close(clients[k].sock); numclients--; } } } }
TCP_Socket::~TCP_Socket() { SDLNet_TCP_DelSocket(sockset, sock); SDLNet_FreeSocketSet(sockset); SDLNet_TCP_Close(sock); }
void Server::Update(){ // CORE LOOP // listen for and handle new connections TCPsocket new_connection = SDLNet_TCP_Accept(server_socket); if (new_connection){ if (players_connected < MAX_PLAYERS){ // add new player SDLNet_TCP_AddSocket(client_sockets, new_connection); client_data.push_back(connection_data(new_connection, SDL_GetTicks(), current_playerId, true)); players_connected++; PlayerObject *newPlayer = new PlayerObject(17); newPlayer->loadTexture(renderer, "other.png"); newPlayer->SetScale(*new Vector2(0.1, 0.1)); playerObjects[current_playerId] = newPlayer; gameObjects.push_back(newPlayer); // inform connected player about self sprintf(outgoing, "0 %i\n", current_playerId); SDLNet_TCP_Send(new_connection, outgoing, 17); for (map<int, PlayerObject*>::iterator i = playerObjects.begin(); i != playerObjects.end(); ++i){ if (i->first == current_playerId){ continue; } // inform other players about new player sprintf(outgoing, "2 %i\n", current_playerId); SDLNet_TCP_Send(client_data[i->first].socket, outgoing, 17); // inform connected player about others sprintf(outgoing, "2 %i\n", i->first); SDLNet_TCP_Send(client_data[current_playerId].socket, outgoing, 17); } printf("New player connected: %i\n", current_playerId); current_playerId++; } else { // server is full printf("New connection attempt but the server was full!\n"); } } // receive data while (SDLNet_CheckSockets(client_sockets, 0) > 0){ for (int i = 0; i < client_data.size(); i++){ if (client_data[i].connected && SDLNet_SocketReady(client_data[i].socket)){ client_data[i].timeout = SDL_GetTicks(); SDLNet_TCP_Recv(client_data[i].socket, incoming, 17); //printf("Player %i: %s\n", client_data[i].player_id, incoming); // TODO: make this more flexible char* parse = strtok(incoming, " "); if (parse){ switch(atoi(parse)){ case 0:{ // 0 = disconnect message // delete from gameObject vector vector<GameObject*>::iterator it = find(gameObjects.begin(), gameObjects.end(), playerObjects[client_data[i].player_id]); if (it != gameObjects.end()){ gameObjects.erase(it); } delete playerObjects[i]; playerObjects.erase(i); // inform other players for (map<int, PlayerObject*>::iterator it = playerObjects.begin(); it != playerObjects.end(); ++it){ if (it->first == client_data[i].player_id){ continue; } sprintf(outgoing, "3 %i\n", client_data[i].player_id); SDLNet_TCP_Send(client_data[it->first].socket, outgoing, 17); } players_connected--; // delete from socket info SDLNet_TCP_DelSocket(client_sockets, client_data[i].socket); client_data[i].connected = false; //client_data.erase(client_data.begin() + i); break; } case 1:{ // 1 = direction update // "1 direction.x direction.y" parse = strtok(NULL, " "); float x = atof(parse); parse = strtok(NULL, " "); float y = atof(parse); playerObjects[client_data[i].player_id]->SetDirection(*new Vector2(x, y)); break; } default: break; } } } } } // collision detection for (int i = 0; i < gameObjects.size(); i++){ if (gameObjects[i]->CanCollide()){ for (int j = i; j < gameObjects.size(); j++){ if (j == i) continue; if (gameObjects[j]->CanCollide()){ gameObjects[i]->Collision(gameObjects[j]); } } } } // update game objects for (int i = 0; i < gameObjects.size(); i++){ gameObjects[i]->Update(); } // send data for (map<int, PlayerObject*>::iterator i = playerObjects.begin(); i != playerObjects.end(); ++i){ // reach every connected player // send position info for (map<int, PlayerObject*>::iterator j = playerObjects.begin(); j != playerObjects.end(); ++j){ sprintf(outgoing, "1 %i %.2f %.2f\n", i->first, i->second->GetPosition().GetX(), i->second->GetPosition().GetY()); SDLNet_TCP_Send(client_data[j->first].socket, outgoing, 17); } // send ball position sprintf(outgoing, "5 %.2f %.2f\n", ball->GetPosition().GetX(), ball->GetPosition().GetY()); SDLNet_TCP_Send(client_data[i->first].socket, outgoing, 17); //printf("data sent: %s", outgoing); } }
void HandleClient(int which) { char data[512]; int i; /* Has the connection been closed? */ if ( SDLNet_TCP_Recv(people[which].sock, data, 512) <= 0 ) { #ifdef DEBUG fprintf(stderr, "Closing socket %d (was%s active)\n", which, people[which].active ? "" : " not"); #endif /* Notify all active clients */ if ( people[which].active ) { people[which].active = 0; data[0] = CHAT_DEL; data[CHAT_DEL_SLOT] = which; for ( i=0; i<CHAT_MAXPEOPLE; ++i ) { if ( people[i].active ) { SDLNet_TCP_Send(people[i].sock,data,CHAT_DEL_LEN); } } } SDLNet_TCP_DelSocket(socketset, people[which].sock); SDLNet_TCP_Close(people[which].sock); people[which].sock = NULL; } else { switch (data[0]) { case CHAT_HELLO: { /* Yay! An active connection */ memcpy(&people[which].peer.port, &data[CHAT_HELLO_PORT], 2); memcpy(people[which].name, &data[CHAT_HELLO_NAME], 256); people[which].name[256] = 0; #ifdef DEBUG fprintf(stderr, "Activating socket %d (%s)\n", which, people[which].name); #endif /* Notify all active clients */ for ( i=0; i<CHAT_MAXPEOPLE; ++i ) { if ( people[i].active ) { SendNew(which, i); } } /* Notify about all active clients */ people[which].active = 1; for ( i=0; i<CHAT_MAXPEOPLE; ++i ) { if ( people[i].active ) { SendNew(i, which); } } } break; default: { /* Unknown packet type?? */; } break; } } }
BOOL system_comms_connect(void) { #ifndef HAVE_LIBSDL_NET if (comms_mode != COMMS_NONE) { printf("no comms support\n"); return FALSE; } return TRUE; #else IPaddress ip; sock = NULL; sockset = NULL; buffered_data = -1; switch (comms_mode) { case COMMS_NONE: return TRUE;; case COMMS_CLIENT: if (comms_host == NULL) { printf("no remote host set\n"); return FALSE; } if (SDLNet_ResolveHost(&ip, comms_host, comms_port) == -1) { printf("cannot resolve host `%s': %s\n", comms_host, SDLNet_GetError()); return FALSE; } sock = SDLNet_TCP_Open(&ip); if(sock == NULL) { printf("cannot connect to %s:%d: %s\n", comms_host, comms_port, SDLNet_GetError()); return FALSE; } break; case COMMS_SERVER: { TCPsocket servsock; if (SDLNet_ResolveHost(&ip, NULL, comms_port) == -1) { printf("cannot create listen address for port %d: %s\n", comms_port, SDLNet_GetError()); return FALSE; } servsock = SDLNet_TCP_Open(&ip); if(servsock == NULL) { printf("cannot listen on port %d: %s\n", comms_port, SDLNet_GetError()); return FALSE; } sockset = SDLNet_AllocSocketSet(1); if (sockset == NULL) { printf("cannot create socket set: %s\n", SDLNet_GetError()); SDLNet_TCP_Close(servsock); comms_shutdown(); return FALSE; } if (SDLNet_TCP_AddSocket(sockset, servsock) < 0) { printf("cannot add socket to socket set: %s\n", SDLNet_GetError()); SDLNet_TCP_Close(servsock); comms_shutdown(); return FALSE; } if (SDLNet_CheckSockets(sockset, -1) < 1) { printf("cannot check socket set: %s\n", SDLNet_GetError()); SDLNet_TCP_Close(servsock); comms_shutdown(); return FALSE; } sock = SDLNet_TCP_Accept(servsock); SDLNet_TCP_Close(servsock); if (sock == NULL) { printf("cannot accept: %s\n", SDLNet_GetError()); comms_shutdown(); return FALSE; } SDLNet_TCP_DelSocket(sockset, servsock); } break; default: return FALSE; } if (sockset == NULL) { sockset = SDLNet_AllocSocketSet(1); if (sockset == NULL) { printf("cannot create socket set: %s\n", SDLNet_GetError()); comms_shutdown(); return FALSE; } } if (SDLNet_TCP_AddSocket(sockset, sock) < 0) { printf("cannot add socket to socket set: %s\n", SDLNet_GetError()); comms_shutdown(); return FALSE; } #ifdef COMMS_DEBUG printf("comms mode %s entered\n", comms_names[comms_mode]); #endif return TRUE; #endif /* HAVE_LIBSDL_NET */ }
int BomberNetClient::handleNet() { char data[1024]; int len; int active = SDLNet_CheckSockets(BomberNetClient::socketset, 0); if (active > 0) { if (SDLNet_SocketReady(BomberNetClient::tcpsock)) { memset(data, 0, sizeof data); len = SDLNet_TCP_Recv(tcpsock, (char *) data, 1024); //fprintf(stderr,"longueur : %i",len); if (len <= 0) { SDLNet_TCP_Close(tcpsock); BomberNetClient::tcpsock = NULL; SDLNet_TCP_DelSocket(BomberNetClient::socketset, BomberNetClient::tcpsock); } else { //fprintf(stderr, "Receive from Server : %s\n", data); //int requestNumber = SDLNet_Read32(data); int type = data[4]; //fprintf(stderr, "request number : %i, %x, %x\n", requestNumber, type, data[5], data[6]); switch (type) { case 0: switch (data[5]) { case 0: //fprintf(stderr, "Nombre de place disponible : %i\n", data[6]); if (data[6] > GameConfig::Instance().getNbPlayerOfClient()) { sendNbPlayerClient(); } else { //fprintf(stderr, "pas assez de place ! %i places libres\n", data[6]); errorValue = data[6]; return 6; } break; case 1: //fprintf(stderr, "serveur plein !"); return 1; case 2: //fprintf(stderr, "serveur en jeu!"); return 2; } break; case 1: switch (data[5]) { case 1: //fprintf(stderr, "Nombre de place disponible : %i", data[6]); if (data[6] == GameConfig::Instance().getNbPlayerOfClient()) { //fprintf(stderr, "Server accept all player"); return 0; } else { //fprintf(stderr, "le serveur ne renvoi pas le nombre correct de joueur"); return 3; } break; case 2: //fprintf(stderr, "le serveur n'acceptera que %i joueurs", data[6]); errorValue = data[6]; return 4; break; } break; case 2: BomberNetClient::viewer->decode(data, len); return 0; break; } } } } else if (active == 0) { //no activity on socket } else { return 5; } return 0; }
int TcpNet::delSocket(const TcpNet::SocketSet set, const TcpNet::Socket sock) { return SDLNet_TCP_DelSocket(set, sock); }
void Network::receive() { SDLNet_SocketSet set; if (!(set = SDLNet_AllocSocketSet(1))) { setError("Error in SDLNet_AllocSocketSet(): " + std::string(SDLNet_GetError())); return; } if (SDLNet_TCP_AddSocket(set, mSocket) == -1) { setError("Error in SDLNet_AddSocket(): " + std::string(SDLNet_GetError())); } while (mState == CONNECTED) { // TODO Try to get this to block all the time while still being able // to escape the loop int numReady = SDLNet_CheckSockets(set, (static_cast<uint32_t>(500))); int ret; switch (numReady) { case -1: logger->log1("Error: SDLNet_CheckSockets"); // FALLTHROUGH case 0: break; case 1: // Receive data from the socket SDL_mutexP(mMutex); ret = SDLNet_TCP_Recv(mSocket, mInBuffer + mInSize, BUFFER_SIZE - mInSize); if (!ret) { // We got disconnected mState = IDLE; logger->log1("Disconnected."); } else if (ret < 0) { setError(_("Connection to server terminated. ") + std::string(SDLNet_GetError())); } else { // DEBUGLOG("Receive " + toString(ret) + " bytes"); mInSize += ret; if (mToSkip) { if (mInSize >= mToSkip) { mInSize -= mToSkip; memmove(mInBuffer, mInBuffer + mToSkip, mInSize); mToSkip = 0; } else { mToSkip -= mInSize; mInSize = 0; } } } SDL_mutexV(mMutex); break; default: // more than one socket is ready.. // this should not happen since we only listen once socket. std::stringstream errorStream; errorStream << "Error in SDLNet_TCP_Recv(), " << numReady << " sockets are ready: " << SDLNet_GetError(); setError(errorStream.str()); break; } } if (SDLNet_TCP_DelSocket(set, mSocket) == -1) logger->log("Error in SDLNet_DelSocket(): %s", SDLNet_GetError()); SDLNet_FreeSocketSet(set); }