Hello everyone,
I have a problemen with some socket communication coding. I have two pi's communicating over TCP/IP with python scripts. The idea is that one pi (client)reads temperature/humidity sensor data and sends it over to the other pi (server), where it will be stored in a SQLite database. In the future I want multiple pi's (clients) sends over sensor data to one (web)server with database to display data on a local website.
I have written some python code for server and client side and it works pretty well. If I start the server side it will listen for other connections. When I start the client side it will generate sensor data and send it to the server. The server receives the data. But when I want to close to connection to make room for (a future other pi) it terminates completely the script and don't listens for new "calls". See code below for both sides. Code is written in Python2.7.
Goal of this project: Within a zoo setting monitor and log multiple exhibits and aquariums on temperature and humidity, display the information on LCD in every exhibit, use LED as warning, and have a central-server to store/log data, that is displayed with a central computer.
RaspiServer - server-side
import socket
from LED import callLED
host = ''
port = 5560
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind complete.")
return s
def setupConnection():
s.listen(1)
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def dataTransfer(conn):
while True:
data = conn.recv(1024)
data = data.decode('utf-8')
dataMessage = data.split(":", 2)
command = dataMessage[0]
humidity = dataMessage[1]
temperature = dataMessage[2]
if command == 'DATA':
print("Received: " + humidity + " : " + temperature)
callLED()
elif command == 'EXIT':
print("Disconnected with Client")
break
else:
reply = 'Unknow Command'
conn.sendall(str.encode(reply))
Print("Reply has been send.")
conn.close()
s = setupServer()
while True:
try:
conn = setupConnection()
dataTransfer(conn)
except:
break
On the client-side there are three python scripts, where the main python scripts communicate with other scripts. I have decides to split it in multiple script to use them also as stand-alone (blinking LED, display data on LCD etc.).
RaspiMonitor - client-side
Run this script on client-side
from time import sleep
from client_sensordata import GetTemp
from monitor_client import transmit
sleepTime = 20
def tempMonitorServer():
humidity, temperature = GetTemp()
temp = str(temperature)
hum = str(humidity)
message = "DATA:" + hum + ":" + temp
print("Transmitting Data.")
response = transmit(message)
print(response)
while True:
tempMonitorServer()
sleep(sleepTime)
Use this script to send and receive data over TCP/IP
import socket
host = '192.168.2.3'
port = 5560
def setupSocket():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
return s
def sendReceive(s, message):
s.send(str.encode(message))
print("Message transmitted")
reply = s.recv(1024)
print("We have received a reply.")
print("Send closing message.")
s.send(str.encode("EXIT"))
s.close()
reply = reply.decode('utf-8')
return reply
def transmit(message):
s = setupSocket()
response = sendReceive(s, message)
return response
Use this script to retrieve sensor data
def GetReading():
import sys
import Adafruit_DHT
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 17)
if humidity is not None and temperature is not None:
print('Reading sensor data')
return humidity, temperature
else:
print('no sensor data')
def GetTemp():
humidity, temperature = GetReading()
name = "DHT22Client1"
print('Read sensor: {0} humidity: {1:0.2f}% temperature: {2:0.2f}C'.format(name, humidity, temperature))
return humidity, temperature
Terminal output
Terminal output, left server and right the client
Could anyone give some tips or help, or tell me why how to fix this problemen? I searched already multiple threads and other posts, but can't find the solution.
Thanks in advance for every help you give.
You have may few error in your server socket setup. The way a server socket works is it should be always open listening for new connection. When you accept a connection from the client(s.accept), it create a connection to the client. If you close that connection , it should not impact the server listening to incomming socket, The number of client or conn to client is limited only by the number you specify in the server socket.listen(NUMBER). When that number is reached, incoming connection will be rejected.
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
s.listen(5)
except socket.error as msg:
print(msg)
print("Socket bind complete.")
return s
Then remove s.listen from setup connection()
I also suggests that you handle data transfer() in a new thread to be able to process incoming connection concurrently insted of consecutive.
Here is a reference: https://docs.python.org/2/howto/sockets.html