Example #1
0
void Server::run()
{
	next_update = 0;
	next_move = 0;
	if (socket.bind(port) != sf::Socket::Done) {
		cout << "Coudn't start server: bind failed" << endl;
		return;
	}
	cout << "Server is listening to port " << port << endl;
	cout << "Protocol message size: " << sizeof(Message) << endl;
	socket.setBlocking(false);
	char in[sizeof(Message)];
	memset(in, '\0', sizeof(Message));
	std::size_t received;
	sf::IpAddress sender;
	unsigned short senderPort;
	sf::Clock clock;
	int previous = clock.getElapsedTime().asMilliseconds();
	game_data = vector<ServerSnake>(0);
	food = vector<Part>(0);
	while (true) {
		sf::Socket::Status s = socket.receive(in, sizeof(in), received, sender, senderPort);
		if (received != 0) {
			Message got = Protocol::decode(in);
			if (got.t < Message::MAX) {
				//cout << (string)sender.toString() << endl;
					//cout<< to_string(senderPort) << endl;
				string UUID = (string)(sender.toString() + to_string(senderPort));
				if (got.t == Message::JOIN) {
					User newUser;
					newUser.ip = sender;
					newUser.port = senderPort;
					newUser.sID = game_data.size();
					users[UUID] = newUser;
					ServerSnake tempSnake;
					tempSnake.dead = false;
					tempSnake.parts = std::vector<Part>(0);
					int div = game_data.size() % 4;
					int x0 = (rand() % (WIDTH / 2 - MIN_PARTS)) + MIN_PARTS;
					int dx = -1;
					if (div > 1) {
						dx = 1;
						//x0 += WIDTH / 2;
					}
					int y0 = rand() % (HEIGHT / 2);
					if (div % 2 == 1)
						y0 += HEIGHT / 2;
					for (int i = 0; i < MIN_PARTS; i++)
					{
						tempSnake.parts.push_back({ (char)(x0 + i * dx), char(y0) });
					}
					if (dx == 1) tempSnake.direction = LEFT;
					else tempSnake.direction = RIGHT;
					game_data.push_back(tempSnake);
					cout << "NEW USER Current users: " << users.size() << endl;
				}
				if (users.count(UUID)>0) {
					User *u = &users[UUID];
					Message tobroadcast=Protocol::make(Message::NONE);
					Message res = u->message(got,game_data, tobroadcast, food);
					if (tobroadcast.t!=Message::NONE) broadcast(UUID, tobroadcast);
					if (res.t != Message::NONE) socket.send(Protocol::encode(res), sizeof(Message) , u->ip, u->port);
				}
				if (got.t == Message::MOVE) {
					for (int i = 0; i < game_data.size(); i++)
					{
						if (users[UUID].sID == i) {
							game_data[i].direction = got.As.move.direction;
						}
					}
				}
			}
		}
		int current = clock.getElapsedTime().asMilliseconds();
		if (current != previous) {
			int steps = current - previous;
			if (users.size() > 0) {
				next_update += steps;
				if (next_update > UPDATEEVERY) {
					update();
					broadcastAll(Protocol::update(game_data, food));
					next_update -= UPDATEEVERY;
				}
			}
			previous = current;
		}
	}
}
Example #2
0
File: ss_2.c Project: jddantes/chat
int main(){
	
	int newfd;
	struct sockaddr_storage remoteaddr;
	socklen_t addrlen;
	
	char buf[800];
	int nbytes;
	
	char remoteIP[INET6_ADDRSTRLEN];
	
	int yes = 1;
	int i, j;
	
	struct addrinfo hints, *ai, *ai_itr;
	
	FD_ZERO(&master);
	FD_ZERO(&read_fds);
	
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	
	int rv;
	if (rv = getaddrinfo(NULL, PORT, &hints, &ai)){
		fprintf(stderr, "server: %s\n", gai_strerror(rv));
		exit(1);
	}
	
	for(ai_itr = ai; ai_itr!=NULL; ai_itr = ai_itr->ai_next) {
		listener = socket(ai_itr->ai_family, ai_itr->ai_socktype, ai_itr->ai_protocol);
		if(listener < 0) {
			continue;		
		}
		setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
		
		if (bind(listener, ai_itr->ai_addr, ai_itr->ai_addrlen) <0 ){
			close(listener);
			continue;
		}
		break;
	}
	
	if (ai_itr == NULL) {
		fprintf(stderr, "server: failed to bind\n");
		exit(2);
	}
	
	freeaddrinfo(ai);
	
	if (listen(listener, 10) == -1) {
		perror("listen");
		exit(3);
	}
	
	FD_SET(listener, &master);
	fdmax = max(fdmax, listener);
	
	sigset_t mask;
	sigset_t orig_mask;
	struct sigaction act;
	memset(&act, 0, sizeof act);
	act.sa_handler = sigint_handler;
	
	sigaction(SIGINT, &act, 0);
	sigemptyset(&mask);
	sigaddset(&mask, SIGINT);
	sigprocmask(SIG_BLOCK, &mask, &orig_mask);
	while(1){
		read_fds = master;
		
		int res;
		if ( (res=pselect(fdmax+1, &read_fds, NULL, NULL, NULL,&orig_mask)) == -1) {
			if(errno!=EINTR){
			perror("select");
			exit(4);}
		}  else if(!res){
			printf("Res == 0\n");
		}
		
		
		
		if(got_int){
			bool hasconnected = false;
			do{
				printf("Cleaning up\n");
				hasconnected = false;
				for(i = 0; i<=fdmax; i++){
					if(FD_ISSET(i, &read_fds) && i!=listener && ol_list[i]){
						char b[200] = {};
						mmsend(i, "[SHUTDOWN]\n");
						int x = recv(i, b, sizeof b, 0);
						
						if(x>0){
							mmsend(i, "[SHUTDOWN]\n");
						}
						
						if(!x){
							
							printf("%d %s closed.\n", i, user_list[i]);
							user_list[i][0] = 0;
							ol_list[i] = 0;
							ip_list[i][0] = 0;
								
						}	
						hasconnected = true;
					
					}
				}
			} while(hasconnected);
			printf("Closed all\n");
			return 0;
		}
		
		for(i = 0; i<=fdmax; i++) { 
			if (FD_ISSET(i, &read_fds)) {
				if (i == listener) { // new connection
					if(got_int) continue;
					addrlen = sizeof remoteaddr;
					newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);
					if(newfd == -1 && !got_int) {
						if(errno != EINTR)
						perror("accept");
					} else {
						FD_SET(newfd, &master);
						fdmax = max(fdmax, newfd);
						printf("server: %s connected on socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr *)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd);
						strcpy(ip_list[newfd], remoteIP);
						user_list[newfd][0] = 0;
						ol_list[newfd] = 0;
					}
					
					
				} else { // handle data from client
					
				
				
					if ( (nbytes = recv(i, buf, sizeof buf, 0)) <= 0  ) {
						if (nbytes == 0 ){
							// connection closed
							printf("server: (%s) on socket %d hung up\n", ip_list[i], i);
							close(i);
							ip_list[i][0] = 0;
							user_list[i][0] = 0;
							ol_list[i] = 0;
							FD_CLR(i, &master);	
							
							// broadcast here
							
						} else {
							if(errno!=EINTR)
							perror("recv");
						}
						
					} else {
						// broadcast here
					
						
						char ret[800];
						currfd = i;
						int bm = handle_data(buf, ret);
						
						if(bm == BROADCAST_SELF){
							msend(i, ret, strlen(ret), 0);
						} else if(bm == BROADCAST_OTHERS){
							
							broadcastOthers(ret, i);	
						} else if(bm == BROADCAST_ALL){
							broadcastAll(ret);
						} else {
							broadcastOne(ret);
						}
					}
				} // END handle data from client
				
			} 
		} // END for loop iteration through file descriptors
		
	} // END while loop
	return 0;
}