How do I send data without it repeating?

Viewed 54

I have a socket connection between client and server. I am able to connect and send data but it keeps repeating the same data instead of stopping/pausing after reading a line.

expected output:

Reading: ls /home

actual output:

Reading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /homeReading: ls /home...

client code:

import socket
import sys

readOut = 0                 # serial data
ipaddr = 'localhost'
ipport = 666

#def hitsocket(ipaddr):
    #with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print ("Starting up")
connected = False

class LineReader:

        def __init__(self, socket, encoding='ascii'):
            self.s = socket
            self.encoding = encoding
            self.buf = b''
            self.closed = False
    
        def readline(self):
            while True:
                index = self.buf.find(b'\n')
                if index >= 0:
                    line = self.buf[:index+1]
                    self.buf = self.buf[index+1:]
                    return line.decode(self.encoding)
                if self.closed:
                    line = self.buf
                    self.buf = b''
                    return line.decode(self.encoding)
                data = self.s.recv(1024)
                self.closed = len(data) == 0
                print("raw recv:", data)
                self.buf += data
    
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        try:
            s.connect((ipaddr , ipport))
            reader = LineReader(s)
            while True:
                line = reader.readline()
                while(line):
                    if not line:
                        break
                    print(f"Reading: {line}", end='')
                    if "Fahrenheit" in line:
                        cread = line[22:-2]
                        newcread = float(cread)
                        print("cread ", cread, 
                              "newcread ", newcread)
        finally:
            print('closing socket', file=sys.stderr)
            s.close()

server code:

import socket
import time

inputdata = input("Enter command: ")
test_data =  bytes(inputdata, encoding='utf-8')
s = socket.socket()
# todo: change as needed, but must match address in client script
s.bind(('localhost', 666))
s.listen()
while True:
    c, addr = s.accept()
    # send in framents to test reassembler
    try:
        if(test_data):
            c.send(test_data)
    except Exception as e:
        print(e)
    time.sleep(.1)
    c.shutdown(socket.SHUT_RDWR)
    c.close()

How to I get my socket connection to read a single line of input and wait for the next?

1 Answers

In the following block of your client code, the value of line never changes in your innermost while loop. And since its a non-empty string, the loop condition is always true, I think changing while with an if might help.

You also don't need the if not line condition after that, which I presume you added while trying to fix your problem.

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    try:
        s.connect((ipaddr , ipport))
        reader = LineReader(s)
        while True:
            line = reader.readline()
            if line:
                print(f"Reading: {line}", end='')
                if "Fahrenheit" in line:
                    cread = line[22:-2]
                    newcread = float(cread)
                    print("cread ", cread, 
                          "newcread ", newcread)
    finally:
        print('closing socket', file=sys.stderr)
        s.close()
Related