示例#1
0
static	void	Read_message()
{

static	char		 mess[MAX_MESSLEN];
	char		 sender[MAX_GROUP_NAME];
	char		 target_groups[MAX_MEMBERS][MAX_GROUP_NAME];
        membership_info  memb_info;
        vs_set_info      vssets[MAX_VSSETS];
        unsigned int     my_vsset_index;
        int              num_vs_sets;
        char             members[MAX_MEMBERS][MAX_GROUP_NAME];
	int		 num_groups;
	int		 service_type;
	int16		 mess_type;
	int		 endian_mismatch;
	int		 i,j;
	int		 ret;

        service_type = 0;

	ret = SP_receive( Mbox, &service_type, sender, 100, &num_groups, target_groups, 
		&mess_type, &endian_mismatch, sizeof(mess), mess );
	printf("\n============================\n");
	if( ret < 0 ) 
	{
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                        service_type = DROP_RECV;
                        printf("\n========Buffers or Groups too Short=======\n");
                        ret = SP_receive( Mbox, &service_type, sender, MAX_MEMBERS, &num_groups, target_groups, 
                                          &mess_type, &endian_mismatch, sizeof(mess), mess );
                }
        }
        if (ret < 0 )
        {
		if( ! To_exit )
		{
			SP_error( ret );
			printf("\n============================\n");
			printf("\nBye.\n");
		}
		exit( 0 );
	}
	if( Is_regular_mess( service_type ) )
	{
		mess[ret] = 0;
		if     ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE ");
		else if( Is_reliable_mess(   service_type ) ) printf("received RELIABLE ");
		else if( Is_fifo_mess(       service_type ) ) printf("received FIFO ");
		else if( Is_causal_mess(     service_type ) ) printf("received CAUSAL ");
		else if( Is_agreed_mess(     service_type ) ) printf("received AGREED ");
		else if( Is_safe_mess(       service_type ) ) printf("received SAFE ");
		printf("message from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, mess_type, endian_mismatch, num_groups, ret, mess );
	}else if( Is_membership_mess( service_type ) )
        {
                ret = SP_get_memb_info( mess, service_type, &memb_info );
                if (ret < 0) {
                        printf("BUG: membership message does not have valid body\n");
                        SP_error( ret );
                        exit( 1 );
                }
		if     ( Is_reg_memb_mess( service_type ) )
		{
			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
				sender, num_groups, mess_type );
			for( i=0; i < num_groups; i++ )
				printf("\t%s\n", &target_groups[i][0] );
			printf("grp id is %d %d %d\n",memb_info.gid.id[0], memb_info.gid.id[1], memb_info.gid.id[2] );

			if( Is_caused_join_mess( service_type ) )
			{
				printf("Due to the JOIN of %s\n", memb_info.changed_member );
			}else if( Is_caused_leave_mess( service_type ) ){
				printf("Due to the LEAVE of %s\n", memb_info.changed_member );
			}else if( Is_caused_disconnect_mess( service_type ) ){
				printf("Due to the DISCONNECT of %s\n", memb_info.changed_member );
			}else if( Is_caused_network_mess( service_type ) ){
				printf("Due to NETWORK change with %u VS sets\n", memb_info.num_vs_sets);
                                num_vs_sets = SP_get_vs_sets_info( mess, &vssets[0], MAX_VSSETS, &my_vsset_index );
                                if (num_vs_sets < 0) {
                                        printf("BUG: membership message has more then %d vs sets. Recompile with larger MAX_VSSETS\n", MAX_VSSETS);
                                        SP_error( num_vs_sets );
                                        exit( 1 );
                                }
                                for( i = 0; i < num_vs_sets; i++ )
                                {
                                        printf("%s VS set %d has %u members:\n",
                                               (i  == my_vsset_index) ?
                                               ("LOCAL") : ("OTHER"), i, vssets[i].num_members );
                                        ret = SP_get_vs_set_members(mess, &vssets[i], members, MAX_MEMBERS);
                                        if (ret < 0) {
                                                printf("VS Set has more then %d members. Recompile with larger MAX_MEMBERS\n", MAX_MEMBERS);
                                                SP_error( ret );
                                                exit( 1 );
                                        }
                                        for( j = 0; j < vssets[i].num_members; j++ )
                                                printf("\t%s\n", members[j] );
                                }
			}
		}else if( Is_transition_mess(   service_type ) ) {
			printf("received TRANSITIONAL membership for group %s\n", sender );
		}else if( Is_caused_leave_mess( service_type ) ){
			printf("received membership message that left group %s\n", sender );
		}else printf("received incorrecty membership message of type 0x%x\n", service_type );
        } else if ( Is_reject_mess( service_type ) )
        {
		printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, service_type, mess_type, endian_mismatch, num_groups, ret, mess );
	}else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret);


	printf("\n");
	printf("User> ");
	fflush(stdout);
}
示例#2
0
int main( int argc, char *argv[] )
{
	int		ret;
	int		service_type, num_groups;
	char		sender[MAX_GROUP_NAME];
	int16		mess_type;
	int		dummy_endian_mismatch;
        int             joined_members;
        int             sender_index;
	int		i,j;

	Usage( argc, argv );

        if (Num_members == 0) {
            /* connecting to the relevant Spread daemon, no need for group info */
            printf("flooder: connecting to %s\n", Spread_name );
            ret = SP_connect( Spread_name, User, 0, 0, &Mbox, Private_group ) ;
        } else {
            /* connecting to the relevant Spread daemon, DO need group info */
            printf("flooder: connecting to %s with group membership\n", Spread_name );
            ret = SP_connect( Spread_name, User, 0, 1, &Mbox, Private_group ) ;
        }
        if(ret < 0) 
	{
		SP_error( ret );
                exit(1) ;
        }
	/* 
	 * Joining the process group.
	 *
	 * Note that this is not necessary in order to multicast the
	 * messages, but only to demonstrate end-to-end behaviour.
	 */
	if( Read_only )
	{
		printf("flooder: Only receiving messages\n");
		SP_join( Mbox, "flooder" );
	}else if( Write_only ) {
		printf("flooder: starting  multicast of %d messages, %d bytes each (self discarding).\n", Num_messages, Num_bytes);
	}else{
		SP_join( Mbox, "flooder" );
		printf("flooder: starting  multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes);
	}

        /* Wait for all members to join */
        joined_members = 0;
        while( joined_members < Num_members)
        {
            service_type = 0;
            ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
                              &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
            if( ret < 0 ) 
            {
                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                    printf("\n========Buffers or Groups too Short=======\n");
                    printf("Should NOT happen in wait for members! Program quitting\n");
                    exit(1);
                }       
            }

            if( Is_regular_mess( service_type ) )
            {
		mess[ret] = 0;
		if     ( Is_unreliable_mess( service_type ) ) printf("received UNRELIABLE ");
		else if( Is_reliable_mess(   service_type ) ) printf("received RELIABLE ");
		else if( Is_fifo_mess(       service_type ) ) printf("received FIFO ");
		else if( Is_causal_mess(     service_type ) ) printf("received CAUSAL ");
		else if( Is_agreed_mess(     service_type ) ) printf("received AGREED ");
		else if( Is_safe_mess(       service_type ) ) printf("received SAFE ");
		printf("message during wait for members, from %s, of type %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess );
            }else if( Is_membership_mess( service_type ) )
            {
		if     ( Is_reg_memb_mess( service_type ) )
		{
			printf("Received REGULAR membership for group %s with %d members, where I am member %d:\n",
				sender, num_groups, mess_type );
			for( i=0; i < num_groups; i++ )
				printf("\t%s\n", &ret_groups[i][0] );
                        /* update count of joined members */
                        joined_members = num_groups;

		}else if( Is_transition_mess(   service_type ) ) {
			printf("received TRANSITIONAL membership for group %s\n", sender );
		}else if( Is_caused_leave_mess( service_type ) ){
			printf("received membership message that left group %s\n", sender );
		}else printf("received incorrecty membership message of type 0x%x\n", service_type );
            } else if ( Is_reject_mess( service_type ) )
            {
		printf("REJECTED message from %s, of servicetype 0x%x messtype %d, (endian %d) to %d groups \n(%d bytes): %s\n",
			sender, service_type, mess_type, dummy_endian_mismatch, num_groups, ret, recv_mess );
            }else printf("received message of unknown message type 0x%x with ret %d\n", service_type, ret);
           
        } /* joined_members < Num_members */

        /* Update My_Counter_index field based on location of my name in last membership message */
        if (Num_members)
        {
            My_Counter_index = mess_type;
            memcpy(&mess[0], &My_Counter_index, sizeof(int));
        }

	for( i=1; i <= Num_messages; i++ )
	{
		/* multicast a message unless Read_only */
		if( !Read_only )
		{
                    if (Num_members) 
                    {
                        ret = SP_multicast( Mbox, FIFO_MESS, "flooder", 0, Num_bytes, mess );
                        Send_Counter++;
                    } else {
                        ret = SP_multicast( Mbox, RELIABLE_MESS, "flooder", 0, Num_bytes, mess );
                    }
		    if( ret != Num_bytes ) 
		    {
			if( ret < 0 )
			{
				SP_error( ret );
				exit(1);
			}
			printf("sent a different message %d -> %d\n", Num_bytes, ret );
		    }
		}

		/* receive a message (Read_only) or one of my messages */
		if( Read_only || ( i > 200 && !Write_only ) )
		{
                    int notdone;

		    do{
                        service_type = 0;

			ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
					  &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
                        if( ret < 0 ) 
                        {
                                if ( (ret == GROUPS_TOO_SHORT) || (ret == BUFFER_TOO_SHORT) ) {
                                        service_type = DROP_RECV;
                                        printf("\n========Buffers or Groups too Short=======\n");
                                        ret = SP_receive( Mbox, &service_type, sender, FLOODER_MAX_GROUPS, &num_groups, ret_groups, 
                                                          &mess_type, &dummy_endian_mismatch, sizeof(recv_mess), recv_mess );
                                }
                        }
			if( ret < 0 )
			{
				SP_error( ret );
				exit(1);
			}
                        if (Num_members) {
                            /* update counters of received messages */
                            memcpy(&sender_index, &recv_mess[0], sizeof(int));
                            Recv_Counters[sender_index]++;
                            /* 
                               printf("DEBUG: updated counter %d to value %d\n", sender_index, Recv_Counters[sender_index]);
                            */
                            if (Recv_Counters[sender_index] == (Lowest_Recv_Counter + 1)) {
                                /* Update Lowest_Recv_Counter */
                                Lowest_Recv_Counter = INT_MAX;
                                for (j=0; j < Num_members; j++) {
                                    if (Recv_Counters[j] == 0) continue;
                                    if (Recv_Counters[j] < Lowest_Recv_Counter)
                                        Lowest_Recv_Counter = Recv_Counters[j];
                                }
                                if (Lowest_Recv_Counter == INT_MAX) 
                                    Lowest_Recv_Counter = 0;
                            }
                            /* Read loop is done if we send messages and we have received all 
                             * other senders messages upto 100 less then our current send count 
                             */
                            notdone = ( Lowest_Recv_Counter < (Send_Counter - 200) && !Read_only );
                        } else {
                            notdone = (strcmp( sender, Private_group ) != 0 && !Read_only);
                        }

		    } while( notdone );
		}

		/* report some progress... */
		if( i%1000 == 0 ) printf("flooder: completed %6d messages of %d bytes\n",i, ret);
	}
	printf("flooder: completed multicast of %d messages, %d bytes each.\n", Num_messages, Num_bytes);

	return 0;
}