11

I am creating a socket client and trying to obtain some data. In order to do so, I need to connect to a web server via socket and the server actually creates another socket which listens and awaits for the data after which sends back to the client.

The problem I have with the code below is that my socket client does not wait for the incoming data from the server and just accepts empty data.

How can I wait for a non-empty data from the server using Python sockets?

My code:

import sys
import json
import socketIO_client
import time

host = 'https://SOME_URL'

socketIO = socketIO_client.SocketIO(host, params={"email" : "edmund@gmail.com"})
def on_connect(*args):
    print "socket.io connected"

def on_disconnect(*args):
    print "socketIO diconnected"

socketIO.on('connect', on_connect)
socketIO.on('disconnect', on_disconnect)

def on_response_state(*args):
    print args # Prints ()

socketIO.emit('receive_state',on_response_state)
socketIO.wait_for_callbacks(seconds=3)
bunbun
  • 2,595
  • 3
  • 34
  • 52
aikhs
  • 949
  • 2
  • 8
  • 20
  • why do you not need a password parameter? I think you need to provide some context of the server, the problem seems to be more than just "requires a while loop" – bunbun Dec 04 '18 at 09:48
  • @bunbun Where do you see a password parameter? I only need an email parameter – aikhs Dec 05 '18 at 07:07
  • you are telling it to only wait for a max of 3 seconds before carrying on with the last line, change that to `socketIO.wait()` to wait for a response. – James Kent Dec 06 '18 at 13:17
  • `Software_delay`,`block_wait`,`block_read` never solve your problem ! Need read some **header** data/bytes (cos `header include content-length`) and wait_until **if last_byte are received**(otherwise already got corrupted data). – dsgdfg Dec 06 '18 at 14:39
  • @JamesKent socketIO.wait() has nothing to do with the data await, it only ensures the duration of the socket connection to the server – aikhs Dec 07 '18 at 09:20

3 Answers3

5

Here's an example using socket. Using s.accept(), the client will wait till a client accepts the connection before starting the while loop to receive data. This should help with your problem.

def receiver():
    PORT = 123
    CHUNK_SIZE = 1024

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('0.0.0.0', PORT))
    s.listen(1)
    conn,address=s.accept()  # accept an incoming connection using accept() method which will block until a new client connects

    while True:
        datachunk = conn.recv(CHUNK_SIZE) # reads data chunk from the socket in batches using method recv() until it returns an empty string
        if not datachunk:
            break  # no more data coming in, so break out of the while loop
        data.append(datachunk)  # add chunk to your already collected data

    conn.close()
    print(data)
    return

receiver()
bunbun
  • 2,595
  • 3
  • 34
  • 52
  • How can I connect to the socket using email as a parameter? And after connecting, how can I emit to a socket parameter? – aikhs Dec 04 '18 at 09:02
1

put the recv socket in a while thread.

like this:

  def rec(self):

    while 1:
        sleep 0.01
        rdata = self.clientsocket.recv(self.buffsize)

        print("rec from server: ", rdata.decode('utf8'),'\n','press enter to continue')

....

t2 = threading.Thread(target=y.rec, name="rec") 

t2.start()
neo
  • 11
  • 2
0

Since you're using the SocketIO library to include parameters (achieved using requests), and want to emit a message, you can wait indefinitely for a response by not specifying a wait time.

with SocketIO(host, params={"email" : "edmund@gmail.com"}) as socketIO:
    def on_response_state(*args):
        print args # Prints ()

    socketIO.emit('receive_state', on_response_state)
    socketIO.wait()
bunbun
  • 2,595
  • 3
  • 34
  • 52
  • unfortunately, your solution does not work. It does not wait for a data, after emitting it goes straight to callback and then the indefinite wait comes – aikhs Dec 07 '18 at 09:20