예제 #1
0
파일: network.cpp 프로젝트: Heark/wesnoth
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;
		}
	}
예제 #2
0
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
	}
}
예제 #3
0
 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;
 }
예제 #4
0
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);
}
예제 #5
0
파일: network.cpp 프로젝트: dailin/wesnoth
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;
}
예제 #6
0
//-----------------------------------------------------------------------------
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;
}
예제 #7
0
 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;
 }
예제 #8
0
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;
}
예제 #9
0
파일: net.c 프로젝트: johan--/netnuclear
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);
   }
}
예제 #10
0
파일: net.cpp 프로젝트: hu9o/smw-next
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--;
			}
		}
	}
}
예제 #11
0
파일: Net.cpp 프로젝트: Zl0bin/493final
 TCP_Socket::~TCP_Socket() {
   SDLNet_TCP_DelSocket(sockset, sock);
   SDLNet_FreeSocketSet(sockset);
   SDLNet_TCP_Close(sock);
 }
예제 #12
0
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);
    }

}
예제 #13
0
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;
		}
	}
}
예제 #14
0
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;
}
예제 #16
0
int TcpNet::delSocket(const TcpNet::SocketSet set, const TcpNet::Socket sock)
{
    return SDLNet_TCP_DelSocket(set, sock);
}
예제 #17
0
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);
}