I have a client class, in which it should connect to the server (in this case, iKettle) and sends and receives data. The IP address should come from another main server (so another class), and this IP address can change.
Below is the client code:
#command codes
_ON = "0x4<LF>"
_OFF = "0x0<LF>"
#base command
_BASE_COMMAND = "set sys output "
_SLEEP_TIME = 0.5
#size of buffer when receiving data
_BUFFER_SIZE = 1024
ip_address = ""
port = 2000
def initialiseSocket(self,ip_address):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip_address, self.port))
return s
def setOn(self,ip_address):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip_address, self.port))
s.send("set sys output 0x4<LF>")
time.sleep(self._SLEEP_TIME)
self.kettleResponse(ip_address)
def setOff(self,ip_address):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip_address, self.port))
s.send(self._BASE_COMMAND + self._OFF)
time.sleep(self._SLEEP_TIME)
self.kettleResponse(ip_address)
def kettleResponse(self,ip_address):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip_address, self.port))
data = s.recv(self._BUFFER_SIZE)
print(data)
And this is an example of commands from another class:
kettle.setOn(KETTLEIP)
However, when running this code, it does not print anything.
Can anyone help please?
2 Answers 2
You're probably connecting and reconnecting too much. Sometimes that simplifies things, but in this case I believe it's making you lose your response.
Try just connecting once, and reusing the socket.
Also, keep in mind that TCP is a byte-oriented protocol, not a message-oriented protocol. IOW, if you send 10k, 10k, 10k, the other side of the TCP socket may receive 5k, 8k, 17k - or even more bizarre possibilities. The total number of bytes will be the same, and the data will arrive in the correct order, but the sizes of the chunks could be totally scrambled. For this reason, most folks use REST with http these days - it's simpler in some ways.
If you're married to TCP, perhaps try my bufsock module (or actually, it's Opensource with a Univ Calif Irvine copyright, but I wrote it while I was working for them, and obtained permission from them to release it). It's at http://stromberg.dnsalias.org/~strombrg/bufsock.html . Its methods behave closer to what most people expect out of TCP.
HTH.
1 Comment
My guess is that you should reuse the socket as @dstromberg indicates:
class Kettle:
# other stuff omitted...
def setOn(self,ip_address):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip_address, self.port))
s.send("set sys output 0x4<LF>")
time.sleep(self._SLEEP_TIME)
self.kettleResponse(s) # pass the socket on
def kettleResponse(self, s):
# don't open a new socket, just reuse s
data = s.recv(self._BUFFER_SIZE)
print(data)
5 Comments
def setCommand(self, ip_address, command): which sends the command and prints the response.'\n' after each command, eg.where you have "set sys output 0x4<LF>" it should be: "set sys output 0x4\n"
kettle.setOn(KETTLEIP)seems like it should run untilprint(data), but you say there is no printout. Does the code get stuck somewhere?class Kettle: