3

So I'm trying to write a program that gets a continuous stream of data from a server, in a thread. The data being sent from the server is always very short, but does range in length

I'm currently trying to use the recv function in the socket library to constantly receive data, but for some reason I'm not getting anything at all. I know a common problem with the recv function is that it sometimes splits up the data, but for me it's not receiving anything. I know that the problem doesn't come from the server, because when the client connects it does receive confirmation from the server. Is this because I'm trying to do this in a different thread?

This is the socket part of my code:

client = socket(AF_INET, SOCK_STREAM)

def connectToServer(host, port):
    global client
    try:
        client.connect((host, port))
        connectionResult = client.recv(2048).decode()
        if connectionResult == 'succesfull connection':
            return connectionResult
        else:
            return 'connection failed'

    except:
        return 'connection failed'

# This function is ran in a thread (from another module)
def getUpdatesFromServer(updateQueue):
    global client
    while True:
        receivedUpdate = client.recv(10000).decode()
        if receivedUpdate == 'server went down':
            updateQueue.put('server went down')

And this is the code that starts the Thread:

getUpdatesFromServerThread = Thread(target=ServerConnect.getUpdatesFromServer, args=(GameState.screenUpdateQueue,))
getUpdatesFromServerThread.daemon = True
getUpdatesFromServerThread.start()

The connectToServer function is called here (the first thing that happens when the client is ran):

connectionOutcome = ServerConnect.connectToServer(host, port)
if connectionOutcome == 'succesfull connection':
    startGame()
else:
    print('\n\nFailed to connect to the server. Please check your internet connection. If your internet connection is okay, it probably means the server is down and you should wait for a while.\n\n')

And here is the startGame function:

def startGame():
    print('You have been succesfully connected to the server.')
    getUpdatesFromServerThread = Thread(target=ServerConnect.getUpdatesFromServer, args=(GameState.screenUpdateQueue,))
    getUpdatesFromServerThread.daemon = True
    getUpdatesFromServerThread.start()
    screenUpdateThread = Thread(target=doScreenUpdates)
    screenUpdateThread.daemon = True
    screenUpdateThread.start()
    sleep(1)
    MainGameScreen.main()
    # When the eventloop stops, this is ran and sends a disconnect signal to the server, which closes the connection (which does work)
    sleep(0.5)
    ServerConnect.sendCommandToServer('disconnect')

Thank you in advance!

Edit: I've found the problem. I thought the server was sending data, but in fact it wasn't, it just didn't give any error message, so I assumed that was working.

MiloTier
  • 31
  • 4
  • How do you know that you do not receive anything? Do you inspect `receivedUpdate` because in your current example you are not sending it onwards anywhere. – JohanL Aug 08 '19 at 13:12
  • What happens when the recv (blocking call) is called it stays there waiting for data ? I believe you have to put more debug logs e.g. before calling recv to make sure that thread is running. Also the connec to server is called before your thread is started. Did you check if there is really data on the socket ? Do netstat -an and check it.. you will see Rec-Q Send-Q – PraveenB Aug 08 '19 at 13:13
  • Yes, I am sure that it's not receiving anything. I have checked and no data is being received and that thread is being called. I am also sure that the server is sending the data. And what should I look for when I use nestat -an? – MiloTier Aug 08 '19 at 13:24
  • Does it start working when you don't use a thread? Decorate your code execution paths with prints so you know where it gets to in the mainline and in the thread? The thread receive doesn't report anything if the message is not 'server went down' so how do you know you aren't receiving anything? Comparing the return value from recv with specific-length strings might work some/most of the time but is very fragile because a socket can split or combine data in arbitrary ways - you need a proper way of handling that once you get this bit of functionality working. – DisappointedByUnaccountableMod Aug 08 '19 at 14:22
  • No, sadly that didn't work. I tried using ```if len(receivedUpdate) > 0:``` but still nothing happened – MiloTier Aug 08 '19 at 14:40
  • non-threading didn't work? setup your own replacement server (it's not difficult in Python I'm sure there are many examples out there) and then you can eliminate the'perhaps the server isn't sending anything' question. – DisappointedByUnaccountableMod Aug 08 '19 at 14:53
  • Were does `connectToServer` get called - add it to your question. – DisappointedByUnaccountableMod Aug 08 '19 at 14:54
  • Actually I am already using a self-made server, made with twisted, running on my localhost. And I am sure that it's sending data, because the confirmation is sent in the same way as when it doesn't work. – MiloTier Aug 08 '19 at 15:10
  • "...I know a common problem with the recv function is that it sometimes splits up the data..." The network splits up data, `recv` dutifully gives you whatever is has available when you ask for it. Your code goes immediately wrong right away at `connectionResult = client.recv(2048).decode()` and continues to go wrong at `receivedUpdate = client.recv(10000).decode()`. You're not understanding that SOCK_STREAM (TCP) is a streaming protocol, instead your pretending its a message protocol. It's not, and this won't work. – President James K. Polk Aug 08 '19 at 15:35
  • Ok, but what do you suggest me using instead? – MiloTier Aug 08 '19 at 15:42
  • Well, I have searched for a while, but I can't find an answer that fits my specific situation. I can't find another question in which recv doesn't return anything. – MiloTier Aug 08 '19 at 17:10
  • [Here](https://stackoverflow.com/q/56813704/238704) is a decent example. – President James K. Polk Aug 08 '19 at 18:40
  • Hmm, I don't think that the function is the problem. I've tried all three examples and none of them return any data. I think I must've made a mistake somewhere, but I just can't figure out where. – MiloTier Aug 09 '19 at 08:47
  • Did you find a solution to your problem, I am also experiencing it? – BAKYAC Dec 28 '21 at 11:00

0 Answers0