Home > Software engineering >  Passing data between functions from endless while loop
Passing data between functions from endless while loop

Time:11-30

Been struggling to get this to work because I can't use return in a while loop that is not going to end.

In a nutshell, I'm receiving a message in a socket client in one function receive() (the endless loop) and need to pass the result of that incoming message to main(). Trying to use yield, since I'm not sure what else would achieve this. I created another function to try and capture the yield in the receive() function.

I know the initial message reaches the server because it outputs the message, and I know the client is receiving the server's confirmation message because it's printing it. I just am having no luck passing that data to main(), so the rest of the code won't work right.

I'm very new to this, so I'm probably doing this horribly wrong. I should be using classes to share data more easily, but don't grasp them enough yet. Hopefully using yield or something else can get around that.

receive function:

def receive():
    while True:
        try:
            incoming = client.recv(2048).decode(FORMAT)
            if 'RECEIVED' in incoming:
                confirmation = 'confirmed'
                yield confirmation
            print(incoming)
        except:
            print("Connection interrupted.")
            client.close()
            break

#------------
# also tried
#------------
def receive():
    while True:
        try:
            incoming = client.recv(2048).decode(FORMAT)
            if 'RECEIVED:COMPLETE' in incoming:
                confirmation = 'confirmed'
            else:
                confirmation = 'unconfirmed'
            yield confirmation
        except:
            print("Connection interrupted.")
            client.close()
            break

return function:

def pass_return(passed_return_value):
    passed_return_value

main function (with various tests)

def main():
    pass_return(receive())
    # Bunch of code
        if something == True:
            send("some message")
            time.sleep(.25)
            try:
                if confirmation == 'confirmed':
                    # do the business here

#------------
# also tried
#------------
def main():
    # Bunch of code
        if something == True:
            send("some message")
            time.sleep(.25)
            pass_return(receive())
            try:
                if confirmation == 'confirmed':
                    # do the business here

#------------
# also tried
#------------
def main():
    r = pass_return(receive())
    # Bunch of code
        if something == True:
            send("some message")
            time.sleep(.25)
            try:
                if r == 'confirmed':
                    # do the business here

#------------
# even tried
#------------
def main():
    # Bunch of code
        if something == True:
            send("some message")
            time.sleep(.25)
            r = pass_return(receive())
            try:
                if r == 'confirmed':
                    # do the business here

I'm declaring the variable confirmation OUTSIDE of main() and receive() (atop the file where my constants are) or else I get an error of confirmation is undefined.

If I print confirmation in main(), it either prints nothing or None, so my guess is that it's just getting the initial empty value of confirmation and not the yield.

# constants above here
confirmation = str()

# code and such
def pass_return(passed_return_value):
    passed_return_value
def receive():
    #code...
def main():
    #code...

if __name__ == '__main__':
    main()

CodePudding user response:

Note that Python is single-threaded. If your program is supposed to do nothing else than waiting for a data to arrive on the socket from an external source, and reacting to it, then this would work:

def receive():
    while True:
        try:
            incoming = client.recv(2048).decode(FORMAT)
            if 'RECEIVED' in incoming:
                yield {'status': 'confirmed', 'message': incoming}
            else:
                yield {'status': 'unconfirmed', 'message': incoming}
        except:
            print("Connection interrupted.")
            client.close()
            break

def main():
    for message in receive():
        print(message)

Here, most of this program's time will be spent on client.recv(2048). This is a blocking call. It does not return until the requested number of bytes is received. Nothing else can happen in your program during this time.

As soon as the bytes are received, you can yield, and the for loop inside main() can process the data. When that's done, the program flow will return to client.recv(2048) and sit there.

If you want different things to happen in your program while it also listens for data on that socket, you will need to look into multithreading, and put this code on a background thread.

  • Related