void ServerApp::SendDisconnectionNotification(SystemAddress& addr)
{
	ClientMap::iterator itr = clients_.find(addr);
	if (itr == clients_.end())
		return;

	unsigned char msgid = ID_LOSTSHIP;
	RakNet::BitStream bs;
	bs.Write(msgid);
	bs.Write(itr->second.id);

	rakpeer_->Send(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, addr, true);

	std::cout << itr->second.id << " has left the game" << std::endl;

	clients_.erase(itr);

	RemoveClientFromList(addr);
}
Example #2
0
int main(int argc, char *argv[])
{
    
    fd_set master;                  // master file descriptor list
    fd_set read_fds;                // temp file descriptor list for select()
    struct sockaddr_in remoteaddr;  // client address
    unsigned ServerPort;            // portnumber of server 
    int fdmax,fdmax_used;           // maximum file descriptor number and helper to find new max 
    int listener;                   // listening socket descriptor
    int newfd;                      // newly accept()ed socket descriptor
    char buf[256];                  // buffer for client data
    int nbytes;
    int addrlen;
    int i, j;
    int NewClient;                  // NewClient ID
    struct timeval timeout;         // timeout 
    int ret; 
    struct ClientListType *ptrNewClient;              // ptr to new & Active Client;
    struct ClientListType *ptrClientRightList;                          // array which contains rights of reg.Clients      
    struct ActiveClientStructType ActiveClientStruct;                       // struct which contains array of active cl.
    
    
    // some command line parsing
    
    if (argc>1) {  // first argument might be a port assignment
	if (*argv[1]=='?') { // ask for help
	    printf("Usage : %s PortNum\n",argv[0]);
	    exit(EXIT_SUCCESS);
	} else {
	    ServerPort=atol(argv[1]);
	}
    } else {
	ServerPort=TCP_CLIENT_PORT;
    }
    
    //  Init Client Access list
    InitClientAccessList(ptrClientRightAscList, &ptrClientRightList);
    
    // Init Active Client List
    InitActiveClientStruct(&ActiveClientStruct);
    
    
    printf("Setup instrument server version %s on port %d ...",VERSION, ServerPort);
    listener=InitTCPListener(ServerPort);
    if (listener<1) {
	perror("TCPListener");
    }
    printf("success\n");
    
    // setup master fd
    FD_ZERO(&master);              // clear the master and temp sets
    FD_ZERO(&read_fds);
    FD_SET(listener, &master);     // add the listener to the master set
    
    // keep track of the biggest file descriptor
    
    fdmax = listener; // so far, it's this one

    for(;;) { // main loop

        // setup fd's timeout and wait for incoming request
        read_fds = master;
        timeout.tv_sec=TCP_CLIENT_WDG;
        timeout.tv_usec=0;
        ret=select(fdmax+1, &read_fds, NULL, NULL, &timeout);
        
        if (ret == -1) { // select error we dare not to handle
            perror("select");
            exit(EXIT_FAILURE);
        }
	
        if (ret) { // lets see what we got
	    for(i = 0; i <= fdmax; i++) {
		if (FD_ISSET(i, &read_fds)) {                                // new msg on i. socket ...
		    if (i == listener) {                                     // listener -> new connection request
			addrlen = sizeof(remoteaddr);			
			if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr,           // first we have to accept
					    &addrlen)) == -1) {
			    perror("accept");
			} else {
			    //Valid client ?
			    if ( ((ptrNewClient=ValidateAddress(&remoteaddr,ptrClientRightList))!=NULL) ) {
				//add new client to active list
				if ((NewClient=AddClientToList(&ActiveClientStruct,ptrNewClient,newfd))<0) { // couldn't add Client to list;
				    printf("no available sockets for fd %d\n",newfd);
				    close(newfd); // close connection
				} else {          // give a positive msg to the log and keep track of maxfd
				    printf("accepted new connection from %s\n",
					   ActiveClientStruct.ptrActiveClientArray[NewClient].ClientName);
				    FD_SET(newfd, &master); // add to master set  
				    if (newfd > fdmax) {    // keep trackof the maximum
					fdmax = newfd;
				    }
				} // endif AddClient
			    } else {   // couldn't find applicant in internal rights list, kick him out
				close(newfd);
				printf("deny access from %s closing..\n",inet_ntoa(remoteaddr.sin_addr));
			    } // endif ValidateAddress
			    
			} // endif accept
		    } else {                                                // handle data from a clients
			if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { // got error or connection closed by client
			    if (nbytes == 0) {                              // connection closed
				ret=RemoveClientFromList(&ActiveClientStruct,i);
				printf("instrumentserver: %s on socket %d hung up\n", 
				       ActiveClientStruct.ptrActiveClientArray[ret].ClientName, i);
			    } else {
				perror("recv");
			    } // EndIf recv
			    close(i); // bye!
			    FD_CLR(i, &master); // remove from master set
			} else { // we got some data from a client
			    
			    // display whats in decimal for first
			    
			    ParseMsg(buf,nbytes,&ActiveClientStruct);
			    
			    for(j = 0; j <= fdmax; j++) {
				// send to everyone
				if (FD_ISSET(j, &master)) {
				    // except the listener and sender
				    if (j != listener && j != i) {
					if (send(j, buf, nbytes, 0) == -1) {
					    perror("send");
					} //endif send					
				    }  // sender and listener
				} // someone in master list
			    } //endfor all clients
			}
		    }
		}
	    }
	} else {
	    for (i = 0; i <= fdmax; i++) {
		if (FD_ISSET(i,&master)) {
		    printf("+");
		    fdmax_used=i;                               // find out what the highest used fd is
		} else {
		    printf(".");
		}
	    }
	    printf("\n");
	    fdmax=fdmax_used;                                  // garbage collection on max fdnum
	}
    } // for main loop
    
    
// release used memory
    
    ReleaseActiveClientStruct(&ActiveClientStruct);            // relase memory of ActiveClientStruct
    ReleaseClientAccessList(ptrClientRightList);               // relase memory of ClientRightList
    
    return EXIT_SUCCESS;
}