Пример #1
0
int setup_network( void )
{
	atexit(network_quit);
	if(hosting)
	{
		network_host(host_port);
		printf("-- waiting for connections.\n");
	}
	else
	{
		network_return_t rv = network_join( host_ip, host_port );
		if( rv != NETWORK_OK )
		{
			puts("-- failed to connect to host");
			puts("-- most likely your arguments were invalid");
			return usage(NULL);
		}
		puts("-- waiting to connect to host.");
		while( network_state == NETWORK_CONNECTING )
			network_pump(NULL,NULL);
		if( network_state == NETWORK_DISCONNECTED )
		{
			puts("-- failed to connect to host to host.");
			exit(1);
		}
		puts("-- successfully connected to host");
	}
	return 0;
}
Пример #2
0
int main(int argc, char**argv)
{

    kprintf("Started Client");

    //Iterator
    int i;

    //host file
    string hostfile;

    //Server Port number
    int server_port;

    //string server port
    string server_port_str;

    //Command file
    string commandfile;

    //client id
    int client_id;

    //Map to store Hostname to IP address
    map<string,string> host_to_id;

    //Map to store Hostname to id
    map<string,int> hostname_to_id;


    //current update
    int current_update;

    if(argc < 9)
    {
        kprintf("Usage: ");
        kprintf("client -s server_port -f command_file -i client_id -h host_file");
        exit(EXIT_FAILURE);
    }

    for(i=0; i<argc; i++)
    {
        string arg = argv[i];
        if(arg == "-s")
        {
            if(argv[i+1])
            {
                string temp = argv[i+1];
                server_port_str = temp;
                server_port = atoi(temp.c_str());
                if(server_port == 0 || (server_port <=1024 || server_port >= 65535))
                {
                    kprintf("Invalid port. Please specify a server port greater than 1024");
                    exit(EXIT_FAILURE);
                }
                i = i + 1;
            }
            else
            {
                kprintf("Please specify server port number");
                exit(EXIT_FAILURE);
            }
        }

        if(arg == "-f")
        {
            if(argv[i+1])
            {
                commandfile = argv[i+1];
                i = i + 1;
            }
            else
            {
                kprintf("Please specify command file");
                exit(EXIT_FAILURE);
            }
        }

        if(arg == "-i")
        {
            if(argv[i+1])
            {
                string temp = argv[i+1];
                client_id = atoi(temp.c_str());
                i = i + 1;
            }
            else
            {
                kprintf("Please specify client id");
                exit(EXIT_FAILURE);
            }
        }

        if(arg == "-h")
        {
            if(argv[i+1])
            {
                hostfile = argv[i+1];
                i = i + 1;
            }
            else
            {
                kprintf("Please specify host file");
                exit(EXIT_FAILURE);
            }
        }

    }

    kprintf("Client ID: ",client_id);
    kprintf("Command file: ",commandfile);
    kprintf("Server Port: ",server_port);


    ifstream hostfile_stream(hostfile.c_str());

    string hostname,hostname_split;
    int host_id = 0;

    if(hostfile_stream.is_open())
    {
        while(hostfile_stream.good())
        {
            getline(hostfile_stream,hostname);
            if(!hostname.empty())
            {
                hostname_to_id[hostname] = host_id;
                kprintf(hostname.c_str(),hostname_to_id[hostname]);
                host_id = host_id + 1;
            }
        }
    }

    //Socket variables for client
    int client_sockfd,n;
    struct sockaddr_in servaddr;
    socklen_t lensock;

    client_sockfd = socket(AF_INET,SOCK_STREAM,0);

    if(client_sockfd == -1)
    {
        kprintf("Could not create socket");
        exit(EXIT_FAILURE);
    }

    ifstream commandfile_stream(commandfile.c_str());

    if(commandfile_stream.is_open())
    {
        while(commandfile_stream.good())
        {
            getline(commandfile_stream,hostname);
            unsigned pos =  hostname.find(" ");

            if(pos != -1)
            {
                string update =  hostname.substr(pos+1);
                int update_length = update.length();
                int hostname_length = hostname.length();
                hostname_split = hostname.substr(0,hostname_length-update_length-1);

                kprintf("hostname",hostname_split.length());
                kprintf("update",update);

                if(!hostname_split.empty())
                {

                    //Get IP address
                    struct hostent *hp;
                    hp = gethostbyname(hostname_split.c_str());

                    if(!hp)
                    {
                        kprintf(" not found ",hostname_split);
                        exit(EXIT_FAILURE);
                    }

                    if((inet_ntoa(*(struct in_addr *)hp->h_addr_list[0])))
                    {
                        string s_local(inet_ntoa(*(struct in_addr *)hp->h_addr_list[0]));
                        kprintf(s_local.c_str());

                        if(s_local.find("127") != 0)
                        {
                            host_to_id[hostname_split] = s_local;
                        }
                        else
                        {
                            host_to_id[hostname_split] = string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]));
                        }
                    }
                    else
                    {
                        host_to_id[hostname_split] = string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]));
                    }
                    kprintf(hostname_split.c_str());


                }

                kprintf("Sending update to: ",host_to_id[hostname_split]);

                //send update
                struct addrinfo hints,*res,*p;
                memset(&hints, 0, sizeof hints);
                hints.ai_family = AF_UNSPEC;
                hints.ai_socktype = SOCK_STREAM;
                getaddrinfo(hostname_split.c_str(),server_port_str.c_str(),&hints,&res);

                char ipstr[INET6_ADDRSTRLEN];

                for(p=res; p!=NULL; p= p->ai_next)
                {
                    void *addr;
                    char *ipver;

                    if(p->ai_family == AF_INET)
                    {
                        struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
                        addr = &(ipv4->sin_addr);
                    }

                    inet_ntop(p->ai_family,addr,ipstr,sizeof(ipstr));

                    string ip_str(ipstr);

                    if(ip_str.find("127") == string::npos)
                    {
                        res->ai_addr = p->ai_addr;
                        res->ai_addrlen = p->ai_addrlen;
                    }

                    printf(" %s:\n",ipstr);
                }



                int rval = connect(client_sockfd,res->ai_addr,res->ai_addrlen);

                if(rval==-1)
                {
                    kprintf("Connect failed skipping update");
                }

                fprintf(stderr,"%d: Sending update %s to server %s\n",client_id,update.c_str(),hostname_split.c_str());

                Client_Update* cli_update = (Client_Update*)malloc(sizeof(Client_Update));
                cli_update->type = TYPE_CLI_UPDATE;
                cli_update->client_id = client_id;
                cli_update->server_id = hostname_to_id[hostname_split];
                kprintf("Server id: ",cli_update->server_id);
                cli_update->timestamp = host_id;
                cli_update->update = atoi(update.c_str());
                host_network(cli_update);

                rval = send(client_sockfd,cli_update,sizeof(Client_Update),0);

                if(rval == -1)
                {
                    kprintf("Send failed");
                    fprintf(stderr,"%d: Unable to send update %s to server %s\n",client_id,update.c_str(),hostname_split.c_str());
                }

                network_host(cli_update);

                char recv_buff[CLIENT_UPDATE_LEN];

                rval = recv(client_sockfd,recv_buff,CLIENT_UPDATE_LEN,0);

                kprintf("Recieved",rval);

                if(rval == 0)
                    fprintf(stderr,"%d: Connection for update %s is closed by server %s\n",client_id,update.c_str(),hostname_split.c_str());
                else if(rval == -1)
                {
                    kprintf("Recv failed");
                }
                else
                {
                    fprintf(stderr,"%d: Update %s sent to server %d is executed\n",client_id,update.c_str(),cli_update->server_id);
                }

            }
            close(client_sockfd);
        }

        commandfile_stream.close();
    }
    else
    {
        kprintf("Unable to read host file");
        exit(EXIT_FAILURE);
    }

}
int main(int argc, char**argv)
{

			//Iterator
		  int i;

		  //Port number
		  int port;

		  //Host file
		  string hostfile;

		  //count of messages to be sent
			int count;

			//Delivery queue
			map<Key,DM*> delivery_queue;

			//Delivered Messages
			vector<Key> delivered_queue;

			//Map to store Hostname to IP address
			map<string,string> host_to_id;

			//Map to store Hostname to id
			map<string,int> hostname_to_id;

			//Map to maintain retransmission info
			map<string,bool> host_retransmit_info;

			//buffer to hold a recieved message
			char *mesg = (char *)malloc(sizeof(AckMessage));

			if(argc < 7)
			{
				kprintf("Usage: ");
				kprintf("proj2 -p port -h hostfile -c count");
				exit(EXIT_FAILURE);
			}

		  for(i=0;i<argc;i++)
		  {
					 string arg = argv[i];
					 if(arg == "-p")
					 {					 			
					 			if(argv[i+1])
								{
									string temp = argv[i+1];
									port = atoi(temp.c_str());
									if(port == 0 || port <=1024)
									{
										kprintf("Invalid port. Please specify a port greater than 1024");
										exit(EXIT_FAILURE);
									}
									i = i + 1;
								}
								else
								{
									kprintf("Please specify port number");
									exit(EXIT_FAILURE);
								}
					 }

					 if(arg == "-h")
					 {	
					 			if(argv[i+1])
								{
									hostfile = argv[i+1];
									i = i + 1;
								}
								else
								{
									kprintf("Please specify host file");
									exit(EXIT_FAILURE);
								}
					 }

					 if(arg == "-c")
					 {
					 			if(argv[i+1])
								{
									string temp = argv[i+1];
									count = atoi(temp.c_str());
									i = i + 1;
									if(count < 0)
									{
										kprintf("Number of messages to be multicast must be greater than zero");
										exit(EXIT_FAILURE);
									}
								}
								else
								{
									kprintf("Please specify number of messages to be multicast");
									exit(EXIT_FAILURE);
								}
					 }

		  }

			kprintf("Port: ",port);
			kprintf("Hostfile: ",hostfile);
			kprintf("Count: ",count);
	
			ifstream hostfile_stream(hostfile.c_str());
		
			string hostname;

			int host_id = 0;

			if(hostfile_stream.is_open())
			{
				while(hostfile_stream.good())
				{		
						getline(hostfile_stream,hostname);		
						if(!hostname.empty())
						{							
							hostname_to_id[hostname] = host_id++;
						
							//Get IP address
							struct hostent *hp;
							hp = gethostbyname(hostname.c_str());
		
							if(!hp)
							{
								kprintf(" not found ",hostname);
								exit(EXIT_FAILURE);			
							}
					
							if((inet_ntoa(*(struct in_addr *)hp->h_addr_list[0])))
							{
									  string s_local(inet_ntoa(*(struct in_addr *)hp->h_addr_list[0]));
	
										kprintf(s_local.c_str());
										
										if(s_local.find("127") != 0)
										{
											host_to_id[hostname] = s_local;
											host_retransmit_info[s_local] = false;
										}
										else
										{
											host_to_id[hostname] = string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]));
											host_retransmit_info[string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]))] = false;
										}
							}
							else
							{
									host_to_id[hostname] = string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]));
									host_retransmit_info[string(inet_ntoa(*(struct in_addr *)hp->h_addr_list[1]))] = false;
							}
							kprintf(hostname.c_str());
	
						}
				}			
				hostfile_stream.close();
			}
			else
			{
				kprintf("Unable to read host file");
				exit(EXIT_FAILURE);
			}

			kprintf("Size is: ",host_to_id.at("xinu01.cs.purdue.edu"));

			//get my hostname
			char myhostname[HOSTNAME_LEN];
			gethostname(myhostname,HOSTNAME_LEN);

			string myhostname_str(myhostname);

			host_retransmit_info[host_to_id[myhostname_str]] = true;

			//Iterator for sending messages		
			int iter=0;

			//Seq numbers to be maintained throughout
			int max_last_proposed_seq_num=0;
			int last_proposed_seq_num = 0;

			//Socket variables
			int sockfd,n;
			struct sockaddr_in servaddr,cliaddr;
			socklen_t lensock;
		
			sockfd = socket(AF_INET,SOCK_DGRAM,0);

			if(sockfd == -1)
			{
				kprintf("Could not create socket");
				exit(EXIT_FAILURE);
			}

			bzero(&servaddr,sizeof(servaddr));
			servaddr.sin_family = AF_INET;
			servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
			servaddr.sin_port=htons(port);
			
			int bval = bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
			
			if(bval==-1)
			{
				kprintf("Bind failed\n");
				exit(EXIT_FAILURE);
			}
			
			//Multiset to maintain all the sequence numbers recieved in Acks
			multiset<int> ackmultiset;


			//infinite loop for the protocol
			while(1)
			{
					//Send message to all other hosts/processes only if iter<count
					if(iter<count)
					{
						DataMessage *init_dm = (DataMessage *)malloc(sizeof(DataMessage));
						init_dm->type = TYPE_DM;
						init_dm->sender = hostname_to_id[myhostname_str];
					
						//Get sender ID
						kprintf("Sender ID: ",init_dm->sender);

						init_dm->msg_id = iter;
						init_dm->data = iter;
					
						host_network(init_dm);

						for(map<string,string>::iterator it	=	host_to_id.begin();it	!= host_to_id.end();++it)
						{
							if(host_retransmit_info[it->second.c_str()] == false)
							{
								cliaddr.sin_family = AF_INET;
								cliaddr.sin_addr.s_addr = inet_addr(it->second.c_str());
								cliaddr.sin_port = htons(port);
								int rval = sendto(sockfd,init_dm,sizeof(DataMessage),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));								
								kprintf("Sent message ",it->second.c_str());
							}
						}					
						
						network_host(init_dm);

						Key current_srch_key (last_proposed_seq_num,hostname_to_id[myhostname_str]);								
				
						//Add the sent message to your queue if it does not already exist
						if(delivery_queue.find(current_srch_key) == delivery_queue.end())
						{
							DM* sent_msg = (DM*)malloc(sizeof(DM));
							sent_msg->deliverable = false;
							sent_msg->seq_num = ++max_last_proposed_seq_num;
							sent_msg->data_msg = init_dm;
							Key current_key (sent_msg->seq_num,hostname_to_id[myhostname_str]);								
							last_proposed_seq_num = max_last_proposed_seq_num;	
							//Add the sent message to your queue
							delivery_queue[current_key] = sent_msg;
							kprintf("Inserted in delivery queue",current_key.seq);
						}
					}

					//Start Recieving messages here
					//start ack timer
					 struct timeval time_ack,time_curr_ack;                            
					 get_now(&time_ack);

					 while(time_to_seconds(&time_ack,get_now(&time_curr_ack)) <= UDP_RETRANSMIT_TIMER)
					 {
					 			
								socklen_t lensock = sizeof(cliaddr);                            
					      if((n = recvfrom(sockfd,mesg,sizeof(AckMessage),MSG_DONTWAIT,(struct sockaddr *)&cliaddr,&lensock)) > 0)
								{
									
									//Get the type by converting from network to host
									uint32_t* recv_type = (uint32_t*)malloc(sizeof(uint32_t));
									memcpy(recv_type,mesg,sizeof(uint32_t));
									int type = *recv_type;
									type = ntohl(type);
			
									kprintf("Recieved Type",type);

									if(type == TYPE_ACK)
									{
												AckMessage* ack_mesg = (AckMessage*)mesg;
												network_host(ack_mesg);
												
												int sender = hostname_to_id[myhostname_str];
												if(ack_mesg->receiver == sender && iter == ack_mesg->msg_id)
												{
													//Mark Ack recieved
													string ip = string(inet_ntoa(cliaddr.sin_addr));
													
													if(host_retransmit_info.find(ip) != host_retransmit_info.end())
													{
														host_retransmit_info[ip] = true;
														kprintf("Marked true for ip ",ip.c_str());
													}
												}
												ackmultiset.insert(ack_mesg->proposed_seq);
									}
									else if(type == TYPE_DM)
									{
										//Check if it is delivered
										DataMessage* dm_mesg = (DataMessage*) mesg;

										network_host(dm_mesg);

										int msg_id = dm_mesg->msg_id;
										int sender = dm_mesg->sender;
										bool delivered = false;

										for(vector<Key>:: iterator it=delivered_queue.begin();it!=delivered_queue.end();++it)
										{
											if((*it).seq == msg_id && (*it).pid == sender)
											{
												delivered = true;
											}
										}
										
										//Check if in ready queue
										bool inreadyqueue = false;

										for(map<Key,DM*>:: iterator it=delivery_queue.begin();it!=delivery_queue.end();it++)
										{
											if((it->second)->data_msg->msg_id == msg_id && (it->second)->data_msg->sender == sender)
												inreadyqueue = true;
										}

										//if not in ready queue or delivered
										if(delivered == false && inreadyqueue == false)
										{
												//Send Ack
												AckMessage* ack_mesg = (AckMessage*)malloc(sizeof(AckMessage));
												ack_mesg->type = TYPE_ACK;
												ack_mesg->sender = hostname_to_id[myhostname_str];
												ack_mesg->msg_id = msg_id;
												ack_mesg->proposed_seq = ++max_last_proposed_seq_num;
												ack_mesg->receiver = sender;
														
												host_network(ack_mesg);		

												//Send ack to the sender
												string ip = string(inet_ntoa(cliaddr.sin_addr));
												cliaddr.sin_family = AF_INET;
												cliaddr.sin_addr.s_addr = inet_addr(ip.c_str());
												cliaddr.sin_port = htons(port);
												int rval = sendto(sockfd,ack_mesg,sizeof(AckMessage),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));								
												kprintf("Sent Ack to ",ip.c_str());
			
												//Store in Queue ********************
												string current_hostname;

												for(map<string,string>:: iterator it=host_to_id.begin(); it!=host_to_id.end(); it++)
												{
													if((it->second).compare(ip) == 0)
														current_hostname = it->first;
												}
												
												DataMessage *init_dm = (DataMessage *)malloc(sizeof(DataMessage));
												init_dm->type = TYPE_DM;
												init_dm->sender = hostname_to_id[current_hostname];
												init_dm->msg_id = msg_id;
												init_dm->data = dm_mesg->data;											

											
												DM* sent_msg = (DM*)malloc(sizeof(DM));
												sent_msg->deliverable = false;
												sent_msg->seq_num = max_last_proposed_seq_num;
												sent_msg->data_msg = init_dm;
												Key current_key (sent_msg->seq_num,hostname_to_id[current_hostname]);								
												last_proposed_seq_num = max_last_proposed_seq_num;

												//Add the sent message to your queue
												delivery_queue[current_key] = sent_msg;
												kprintf("Inserted in delivery queue",current_key.seq);
										}
									}
									else if(type == TYPE_SEQ_MSG)
									{
												SeqMessage* seq_mesg = (SeqMessage*)mesg;	
												
												network_host(seq_mesg);

												int msg_id = seq_mesg->msg_id;
												int sender = seq_mesg->sender;

												//Search in delivery queue for the corresponding message
												for(map<Key,DM*>:: iterator it=delivery_queue.begin();it!=delivery_queue.end();it++)
												{
													if((it->second)->data_msg->msg_id == msg_id && (it->second)->data_msg->sender == sender)
														{
															(it->second)->deliverable = true;
															(it->second)->seq_num = seq_mesg->final_seq;
														}
												}
												max_last_proposed_seq_num = seq_mesg->final_seq;
												deliver_messages(&delivery_queue,&delivered_queue,hostname_to_id[myhostname_str]);
												kprintf("Got final seq message", seq_mesg->msg_id);

									}						
								}

					 }
												 

					//go for next message
					if(check(host_retransmit_info))
					{
													kprintf("After check");

													//Get the maximum sequence number recieved
													int max = *(ackmultiset.rbegin());

													kprintf("Max is",max);

													//Update the max proposed seq num for next message
													if(max_last_proposed_seq_num < max)
														max_last_proposed_seq_num = max;

													//Build the final seq message
													SeqMessage* final_seq_msg = (SeqMessage *)malloc(sizeof(SeqMessage));
													final_seq_msg->type = TYPE_SEQ_MSG;
													final_seq_msg->sender = hostname_to_id[myhostname_str];
													final_seq_msg->msg_id = iter;
													final_seq_msg->final_seq = max;

													host_network(final_seq_msg);

													//send it to everyone
													for(map<string,string>::iterator it	=	host_to_id.begin();it	!= host_to_id.end();++it)
													{
															if(myhostname_str.compare(it->first) !=0)
															{
																cliaddr.sin_family = AF_INET;
																cliaddr.sin_addr.s_addr = inet_addr(it->second.c_str());
																cliaddr.sin_port = htons(port);
																int rval = sendto(sockfd,final_seq_msg,sizeof(SeqMessage),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));								
																kprintf("Sent final sequence message ",it->second.c_str());
															}
													}
													
												int msg_id_srch = iter;
												int sender = hostname_to_id[myhostname_str];

												//update the message in delivery queue with the final sequence number
												for(map<Key,DM*>:: iterator it = delivery_queue.begin();it != delivery_queue.end();++it)
												{
														if(it->second->data_msg->sender == sender && it->second->data_msg->msg_id == msg_id_srch)
														{

															//Prepare new message
															DM* updatedDM = (DM*)malloc(sizeof(DM));	
															updatedDM->data_msg = it->second->data_msg;
															updatedDM->deliverable = true;
															updatedDM->seq_num = max;
														
															//erase the old msg
															delivery_queue.erase(it);
															
															//Prepare new key
															Key updated_key(max,sender);

															//Update queue
															delivery_queue[updated_key] = updatedDM;

															kprintf("Found the message and marked deliverable and updated sequence number too",updatedDM->seq_num);

														}
												}
												
					//deliver messages
					deliver_messages(&delivery_queue,&delivered_queue,hostname_to_id[myhostname_str]);
		
					iter++;	
					//Reinitialize for new message
					host_retransmit_info = reinit(host_retransmit_info,host_to_id[myhostname_str]);

					//Reinitialize ack multiset
					ackmultiset = reinit_set(ackmultiset);
				}
	

				
			}

}