mirror of
https://github.com/uhi22/pyPLC.git
synced 2025-02-08 01:57:10 +00:00
client server demo works
This commit is contained in:
parent
1d0c83839d
commit
bab27a20c5
1 changed files with 70 additions and 17 deletions
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
# Server on a non-blocking socket
|
# Server and client on a non-blocking socket
|
||||||
#
|
#
|
||||||
# explanation of socket handling:
|
# explanation of socket handling:
|
||||||
# https://docs.python.org/3/howto/sockets.html
|
# https://docs.python.org/3/howto/sockets.html
|
||||||
|
@ -12,20 +12,32 @@ import socket
|
||||||
import select
|
import select
|
||||||
import sys # for argv
|
import sys # for argv
|
||||||
import time # for time.sleep()
|
import time # for time.sleep()
|
||||||
|
import errno
|
||||||
|
|
||||||
class pyPlcClientSocket():
|
class pyPlcClientSocket():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||||
self.isConnected = False
|
self.isConnected = False
|
||||||
|
self.rxData = []
|
||||||
|
|
||||||
def connect(self, host, port):
|
def connect(self, host, port):
|
||||||
try:
|
try:
|
||||||
|
print("connecting...")
|
||||||
|
# for connecting, we are still in blocking-mode because
|
||||||
|
# otherwise we run into error "[Errno 10035] A non-blocking socket operation could not be completed immediately"
|
||||||
|
# We set a shorter timeout, so we do not block too long if the connection is not established:
|
||||||
|
self.sock.settimeout(0.5)
|
||||||
self.sock.connect((host, port))
|
self.sock.connect((host, port))
|
||||||
|
self.sock.setblocking(0) # make this socket non-blocking, so that the recv function will immediately return
|
||||||
self.isConnected = True
|
self.isConnected = True
|
||||||
except:
|
except socket.error as e:
|
||||||
|
print("connection failed", e)
|
||||||
self.isConnected = False
|
self.isConnected = False
|
||||||
|
|
||||||
def mysend(self, msg):
|
def transmit(self, msg):
|
||||||
|
if (self.isConnected == False):
|
||||||
|
# if not connected, just ignore the transmission request
|
||||||
|
return -1
|
||||||
totalsent = 0
|
totalsent = 0
|
||||||
MSGLEN = len(msg)
|
MSGLEN = len(msg)
|
||||||
while (totalsent < MSGLEN) and (self.isConnected):
|
while (totalsent < MSGLEN) and (self.isConnected):
|
||||||
|
@ -33,14 +45,47 @@ class pyPlcClientSocket():
|
||||||
sent = self.sock.send(msg[totalsent:])
|
sent = self.sock.send(msg[totalsent:])
|
||||||
if sent == 0:
|
if sent == 0:
|
||||||
self.isConnected = False
|
self.isConnected = False
|
||||||
raise RuntimeError("socket connection broken")
|
print("socket connection broken")
|
||||||
|
return -1
|
||||||
totalsent = totalsent + sent
|
totalsent = totalsent + sent
|
||||||
except:
|
except:
|
||||||
self.isConnected = False
|
self.isConnected = False
|
||||||
|
return -1
|
||||||
|
return 0 # success
|
||||||
|
|
||||||
def isRxDataAvailable(self):
|
def isRxDataAvailable(self):
|
||||||
# todo
|
# check for availability of data, and get the data from the socket into local buffer.
|
||||||
# ... = self.sock.recv(..., 2048))
|
if (self.isConnected == False):
|
||||||
return 0
|
return False
|
||||||
|
blDataAvail=False
|
||||||
|
try:
|
||||||
|
msg = self.sock.recv(4096)
|
||||||
|
except socket.error as e:
|
||||||
|
err = e.args[0]
|
||||||
|
if err == errno.EAGAIN or err == errno.EWOULDBLOCK:
|
||||||
|
# this is the normal case, if no data is available
|
||||||
|
# print('No data available')
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# a "real" error occurred
|
||||||
|
# print("real error")
|
||||||
|
# print(e)
|
||||||
|
self.isConnected = False
|
||||||
|
else:
|
||||||
|
if len(msg) == 0:
|
||||||
|
# print('orderly shutdown on server end')
|
||||||
|
self.isConnected = False
|
||||||
|
else:
|
||||||
|
# we received data. Store it.
|
||||||
|
self.rxData = msg
|
||||||
|
blDataAvail=True
|
||||||
|
return blDataAvail
|
||||||
|
|
||||||
|
def getRxData(self):
|
||||||
|
# provides the received data, and clears the receive buffer
|
||||||
|
d = self.rxData
|
||||||
|
self.rxData = []
|
||||||
|
return d
|
||||||
|
|
||||||
class pyPlcTcpServerSocket():
|
class pyPlcTcpServerSocket():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -72,9 +117,11 @@ class pyPlcTcpServerSocket():
|
||||||
|
|
||||||
def transmit(self, txMessage):
|
def transmit(self, txMessage):
|
||||||
numberOfSockets = len(self.read_list)
|
numberOfSockets = len(self.read_list)
|
||||||
if (numberOfSockets!=2):
|
if (numberOfSockets<2):
|
||||||
print("we have " + str(numberOfSockets) + ", we should have 2, one for accepting and one for data transfer. Will not transmit.")
|
# print("we have " + str(numberOfSockets) + ", we should have 2, one for accepting and one for data transfer. Will not transmit.")
|
||||||
return -1
|
return -1
|
||||||
|
# Simplification: We will send to the FIRST open connection, even we would have more connections open. This is
|
||||||
|
# ok, because in our use case we have exactly one client.
|
||||||
totalsent = 0
|
totalsent = 0
|
||||||
MSGLEN = len(txMessage)
|
MSGLEN = len(txMessage)
|
||||||
while totalsent < MSGLEN:
|
while totalsent < MSGLEN:
|
||||||
|
@ -83,12 +130,11 @@ class pyPlcTcpServerSocket():
|
||||||
print("socket connection broken")
|
print("socket connection broken")
|
||||||
return -1
|
return -1
|
||||||
totalsent = totalsent + sent
|
totalsent = totalsent + sent
|
||||||
return 0
|
return 0 # success
|
||||||
|
|
||||||
def mainfunction(self):
|
def mainfunction(self):
|
||||||
# The select() function will block until one of the socket states has changed.
|
# The select() function will block until one of the socket states has changed.
|
||||||
# We specify a timeout, to be able to run it in the main loop.
|
# We specify a timeout, to be able to run it in the main loop.
|
||||||
# print("before select")
|
|
||||||
timeout_s = 0.05 # 50ms
|
timeout_s = 0.05 # 50ms
|
||||||
readable, writable, errored = select.select(self.read_list, [], [], timeout_s)
|
readable, writable, errored = select.select(self.read_list, [], [], timeout_s)
|
||||||
for s in readable:
|
for s in readable:
|
||||||
|
@ -133,7 +179,13 @@ def testServerSocket():
|
||||||
d = s.getRxData()
|
d = s.getRxData()
|
||||||
print("received " + str(d))
|
print("received " + str(d))
|
||||||
msg = "ok, you sent " + str(d)
|
msg = "ok, you sent " + str(d)
|
||||||
|
print("responding " + msg)
|
||||||
s.transmit(bytes(msg, "utf-8"))
|
s.transmit(bytes(msg, "utf-8"))
|
||||||
|
if ((nLoops % 50)==0):
|
||||||
|
print("trying to send something else")
|
||||||
|
msg = "ok, something else..."
|
||||||
|
s.transmit(bytes(msg, "utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def testClientSocket():
|
def testClientSocket():
|
||||||
print("Testing the pyPlcTcpClientSocket...")
|
print("Testing the pyPlcTcpClientSocket...")
|
||||||
|
@ -141,12 +193,13 @@ def testClientSocket():
|
||||||
c.connect('fe80::e0ad:99ac:52eb:85d3', 15118)
|
c.connect('fe80::e0ad:99ac:52eb:85d3', 15118)
|
||||||
print("connected="+str(c.isConnected))
|
print("connected="+str(c.isConnected))
|
||||||
print("sending something to the server")
|
print("sending something to the server")
|
||||||
c.mysend(bytes("Test", "utf-8"))
|
c.transmit(bytes("Test", "utf-8"))
|
||||||
print("waiting 3s")
|
for i in range(0, 10):
|
||||||
time.sleep(3)
|
print("waiting 1s")
|
||||||
if (c.isRxDataAvailable()):
|
time.sleep(1)
|
||||||
d = c.getRxData()
|
if (c.isRxDataAvailable()):
|
||||||
print("received " + str(d))
|
d = c.getRxData()
|
||||||
|
print("received " + str(d))
|
||||||
print("end")
|
print("end")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue