why doesn't this code receive string ?(it just receive the first character)
Interrupts are designed to do a short bit of work and then leave.  You might think of them as an add-on to the main-loop-only structure.  For example:

void main(void)
{
    //startup initialization
    while(1)
    {
        if(flag1)
        {
            flag1 = 0;
            //do something triggered by flag1
        }
        if(flag2)
        {
            flag2 = 0;
            switch(flag2_state)
            {
            case 0:
                //do action0 from flag2
                break;
            case 1:
                //do action1 from flag2
                break;
            //etc.
            default:
                //correct an invalid state
                break;
            }
            flag2_state++;
        }
        //etc.
    }
}


Notice how flag2's handler does different things each time it's triggered, but always leaves to allow the rest of the code to keep running.  This is the difference between running on "bare metal" as you are, and running on a multithreaded task manager like you would have as part of an operating system like Windows, Mac, or Linux.  Once you understand that, then we can introduce interrupts:

void main(void)
{
    //startup initialization
    while(1)
    {
        if(flag1)
        {
            flag1 = 0;
            //do something triggered by flag1
        }
        //etc.
    }
}
interrupt [flag2] void flag2_isr(void)
{
    flag2 = 0;
    switch(flag2_state)
    {
    case 0:
        //do action0 from flag2
        break;
    case 1:
        //do action1 from flag2
        break;
    //etc.
    default:
        //correct an invalid state
        break;
    }
    flag2_state++;
}


I'm making some assumptions here about the syntax, but I think you get the idea.  The whole point of interrupts is to reduce the latency of certain events, or in other words, the time it takes to handle them.

In the first example, if flag1 and flag2 were to both come on immediately after you check flag2, and flag1 takes a long time to process, then flag2 would have to wait that long to even start.  That might not be acceptable.

In the second example, flag2 is handled immediately, even if flag1 is still processing.  But it becomes much more important to actually leave the ISR because it completely blocks the main loop from doing anything.

Physically, an interrupt is a function-call that is done automatically by the hardware in response to flag2.  Because this can happen at any time without warning, you have to design the interaction well to avoid some weird bugs.  (the volatile keyword is really helpful here)  It's also more important than before to clear flag2, or the function-call will happen again, and again, and again, burning through the state machine like it wasn't even there, and blocking main loop almost as if you're not leaving the ISR at all.



Once you understand that, I can explain that the reason that blocking code (your original example) works on a multitasking operating system (there are several ways to do it; this is just one of them) is that the OS has a user-invisible interrupt that is triggered from a timer.  This can do all sorts of things that are based on a time interval, in addition to switching tasks.  To make the switch, just save the stack pointer (which context am I running in?) to an OS-managed library and load a different one from that same library.  Now when the ISR leaves, it goes to a different task.  Thus, each task can be written as if it's the only thing running.  Not so on bare metal because you don't have that context switcher.