John
John

Reputation: 847

python sockets can't send multiple messages -- data is referenced before assignment--

Hi i'm trying to send multiple messages to the tcp server but in my client i got an error that data is referenced before assignment. If i send one message there will be no error but if i try to send more than one it returns the error.

tcp server:

class Connect(object):

    def __init__(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        except:
            print('socket cannot be created')
        server_address = ('169.254.34.240', 10000)
        #print('starting up: ' + server_address)
        self.sock.bind(server_address)
        self.sock.listen(1)

    def listen(self):
        while True:
            connection, client_address = self.sock.accept()
            print('client connected')
            try:
                data = connection.recv(16)
                print(data)
                if data == "STATUS":
                    connection.sendall("vision=ready")
                elif data == "MEASURE":
                    connection.sendall("vision=computing")
                elif data == "GET_RESULT":
                    connection.sendall("x=1.5,y=0.25,z=0.14,a=0.15")
                else:
                    connection.sendall("wrong command")
            finally:
                connection.close()


def main():
    connect = Connect()
    connect.listen()

if __name__=='__main__':
    main() 

my tcp client which is sending messages:

class Connect(object):

    def __init__(self): 
        # Create a TCP/IP socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Connect the socket to the port on the server given by the caller
        print('connecting to host')
        self.sock.connect(('169.254.34.240',10000))

    def send(self, command):
        try:
            message = command
            print('sending: ' + message)
            self.sock.sendall(message)
            amount_received = 0
                amount_expected = len(message)
                while amount_received < amount_expected:
                    data = self.sock.recv(16)
                    amount_received += len(data)
                    print('received: ' + data)
        finally:
            self.sock.close()
            return data

def main():
    connect = Connect()
    print connect.send("STATUS")
    print connect.send("MEASURE")

if __name__=='__main__':
    main()

so anyone an idea, i suppose i don't end correctly or something, i thought it had something to do about my while in the client?

Upvotes: 2

Views: 9644

Answers (2)

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44092

Providing full stack trace would help, pointing to exact line, where is the problem present. Learn reading these stack traces, they look boring, but provide valuable information like source file and line where it comes from.

Reading your code I suspect, that it fails at finally block, where you return data.

data will not have assigned value in case, the while amount_received < amount_expected would not allow even the first round in the loop or if withing that loop would happen an exception on the line self.sock.recv(16).

Btw.: you are assuming, that length of response will be the same as length of request, but your server does not provide responses with such length.

Upvotes: 0

veiset
veiset

Reputation: 2003

The problem is that you are calling self.sock.close() after each request without creating a new socket. You will need to create a new socket after each time you close it.

You can solve this by creating a connection per request as follows:

class Connect(object):

    def connect(self):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print('connecting to host')
        sock.connect(('127.0.0.1',10000))
        return sock

    def send(self, command):
        sock = self.connect()
        recv_data = ""
        data = True

        print('sending: ' + command)
        sock.sendall(command)

        while data:
            data = sock.recv(1024)
            recv_data += data 
            print('received: ' + data)

        sock.close()
        return recv_data


def main():
    connect = Connect()
    print connect.send("STATUS")
    print connect.send("MEASURE")

Upvotes: 3

Related Questions