2

I've made a code which is able to receive data from the port over TCP protocol. I receive data from ESP8266 every 15 minutes, and then ESP goes to a deepSleep mode. How to change it to make it work continuosly? I wanted to create a new connection in while loop, but it doesn't work.

My code

import sys
import socket

TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0

#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)

#print 'Listening for client...'

#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((TCP_IP,TCP_PORT))
    s.listen(1)

    print 'Listening for client...'
    conn, addr = s.accept()
    print 'Connection address:', addr
    data = conn.recv(BUFFER_SIZE)
    if data == ";" :
            conn.close()
            print "Received all the data"
            i=0
            for x in param:
                    print x
            #break
    elif data:
            print "received data: ", data
            param.insert(i,data)
            i+=1
            #print "End of transmission"

EDIT:

My code after modification.

import sys
import socket

TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0

#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)

#print 'Listening for client...'

#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((TCP_IP,TCP_PORT))
    s.listen(1)
    while 1: 
            print 'Listening for client...'
            conn, addr = s.accept()
            print 'Connection address:', addr
            data = conn.recv(BUFFER_SIZE)
            if data == ";" :
                    conn.close()
                    print "Received all the data"
                    i=0
                    for x in param:
                            print x
                    #break
            elif data:
                    print "received data: ", data
                    param.insert(i,data)
                    i+=1
                    #print "End of transmission"
    s.close()

I created second while loop. I can listen continuously now, but I receive only one packet from the ESP (ESP send 9 packets). How to solve that issue?

1 Answers1

6

If you want to continuously listen for connections and data from your remote end, you can achieve this using select()

A modified version of your code that uses select() is shown below. This will also handle the remote end closing the connection:

import sys
import socket
import select

TCP_IP = '127.0.0.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []

print 'Listening for client...'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP,TCP_PORT))
server.listen(1)
rxset = [server]
txset = []

while 1:
    rxfds, txfds, exfds = select.select(rxset, txset, rxset)
    for sock in rxfds:
        if sock is server:
            conn, addr = server.accept()
            conn.setblocking(0)
            rxset.append(conn)
            print 'Connection from address:', addr
        else:
            try:
                data = sock.recv(BUFFER_SIZE)
                if data == ";" :
                    print "Received all the data"
                    for x in param:
                        print x
                    param = []
                    rxset.remove(sock)
                    sock.close()
                else:
                    print "received data: ", data
                    param.append(data)
            except:
                print "Connection closed by remote end"
                param = []
                rxset.remove(sock)
                sock.close()

NB I've replaced your IP address with the loopback but you get the idea.

Hope this may be helpful.

AS Mackay
  • 2,831
  • 9
  • 19
  • 25
  • Marked. Thanks once again – Marco Svizzeri Nov 16 '17 at 15:26
  • One more question. What if I want to listen to 2 clients on the same port? Should I use multithreading or is there any different solution? I can listen to 2 ports simultaneously now, though, but sometimes I got a collision. I'm receiving data form to ESP8266s but sometimes I don't get what I expect for example: 2:T=25.20H=35.10 1:T=25.40H=38.90 2:T=25.20H=35.10;1 How to avoid that situation? – Marco Svizzeri Dec 05 '17 at 20:52
  • 1
    OK, if you want multiple clients then you will need to maintain multiple param[] lists, one for each client, so data from each client can be saved separately. You can use a dictionary for this, with sock as the key. – AS Mackay Dec 06 '17 at 07:59