• Tcl server receiving empty string from python client

    From Shaun Kulesa@21:1/5 to All on Mon Apr 10 10:34:23 2023
    Hello, I was testing sockets in tcl and I got a tcl server and tcl client to communicate correctly.

    I thought I would try using a python client to send data to my tcl server.

    The python client will send data but the tcl server will output it as a empty string when I get it from the channel.

    I was wondering if this was the tcl servers fault or the python clients fault?

    Thanks.

    server:

    proc accept {chan addr port} {
    fconfigure $chan -blocking 0 -buffering line
    fileevent $chan readable [list receive $chan]

    puts "$addr joined"
    }

    proc receive {channel} {
    puts [chan gets $channel]

    close $channel
    }

    socket -server accept 5000
    vwait forever

    client:

    import socket

    def client_program():
    host = "shaun.rubenportier.be" # as both code is running on same pc
    port = 5000 # socket server port number

    client_socket = socket.socket() # instantiate
    client_socket.connect((host, port)) # connect to the server

    message = input(" -> ") # take input


    client_socket.send(message.encode()) # send message


    client_socket.close() # close the connection

    if __name__ == '__main__':
    client_program()

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Kulesa@21:1/5 to All on Mon Apr 10 12:46:25 2023
    I've tried a mix of combinations using the new line character but the output is still an empty string.

    message = input(" -> ") # take input
    client_socket.send("\n".encode())
    client_socket.send(("\n" + message).encode())
    client_socket.send("\n".encode())

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Shaun Kulesa on Mon Apr 10 15:49:03 2023
    On 4/10/2023 3:46 PM, Shaun Kulesa wrote:
    I've tried a mix of combinations using the new line character but the output is still an empty string.

    message = input(" -> ") # take input
    client_socket.send("\n".encode())
    client_socket.send(("\n" + message).encode()) client_socket.send("\n".encode())


    Interesting... I think newlines should not be encoded - they will cease
    to become newlines.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Shaun Kulesa on Mon Apr 10 15:32:48 2023
    On 4/10/2023 1:34 PM, Shaun Kulesa wrote:
    Hello, I was testing sockets in tcl and I got a tcl server and tcl client to communicate correctly.

    I thought I would try using a python client to send data to my tcl server.

    The python client will send data but the tcl server will output it as a empty string when I get it from the channel.

    I was wondering if this was the tcl servers fault or the python clients fault?


    Not user fault then :-)

    Add a newline character yo your messages when sending them from Python,
    within this line or as a new subsequent message, and see if it improves
    things:

    client_socket.send(message.encode()) # send message

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Kulesa@21:1/5 to All on Mon Apr 10 12:57:12 2023
    Unfortunately the argument has to be in bytes.

    I changed the tcl server receive function to do 3 outputs to match the inputs given by the python client but none of them had the input message from the client as they were all empty strings.

    proc receive {channel} {
    puts [chan gets $channel]
    flush $channel
    puts [chan gets $channel]
    flush $channel
    puts [chan gets $channel]
    flush $channel

    close $channel
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Shaun Kulesa on Mon Apr 10 16:04:21 2023
    On 4/10/2023 3:57 PM, Shaun Kulesa wrote:
    Unfortunately the argument has to be in bytes.

    I changed the tcl server receive function to do 3 outputs to match the inputs given by the python client but none of them had the input message from the client as they were all empty strings.



    Try removing the buffering from this line on the tcl side:

    fconfigure $chan -blocking 0 -buffering line

    to this:

    fconfigure $chan -blocking 0

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Mon Apr 10 22:06:20 2023
    Am 10.04.23 um 19:34 schrieb Shaun Kulesa:

    server:

    proc accept {chan addr port} {
    fconfigure $chan -blocking 0 -buffering line
    fileevent $chan readable [list receive $chan]

    puts "$addr joined"
    }

    proc receive {channel} {
    puts [chan gets $channel]

    close $channel
    }


    I don't know how well non-blocking I/O and gets work together. It may
    well be that the first read receives nothing and the second read would
    deliber the data. Try changing the receiver like this:

    proc receive {channel} {
    puts "Got: [read $channel]"
    }

    Does it change anything? The server won't stop then after 1 line,
    obviously, but maybe it spits out an empty string and then the
    transmitted data.

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Shaun Kulesa on Mon Apr 10 20:49:11 2023
    Shaun Kulesa <[email protected]> wrote:
    Unfortunately the argument has to be in bytes.

    I changed the tcl server receive function to do 3 outputs to match
    the inputs given by the python client but none of them had the input
    message from the client as they were all empty strings.

    proc receive {channel} {
    puts [chan gets $channel]
    flush $channel
    puts [chan gets $channel]
    flush $channel
    puts [chan gets $channel]
    flush $channel

    close $channel
    }

    Reread the Tcl 'gets' man page, specifically the part about
    'non-blocking' IO.

    If channelId is in non-blocking mode and there is not a full
    line of input available, the command returns an empty string and
    does not consume any input.

    In 'non-blocking' mode, returning "empty string" is Tcl's way of
    indicating "not a full line available".

    If you use the alternate gets call, with a varname into which to store
    the string, then you'll receive -1 as the length from gets when it
    returns the "not enough data for a full line" indication.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Kulesa@21:1/5 to All on Mon Apr 10 13:37:29 2023
    Thanks Christian Gollwitzer, I tested that with two inputs on one connection and it receives both of them. I'm trying to close the connection after the client disconnects as it creates an infinite loop of printing "Got: ".

    I got it to work as it closes the socket connection but the receive function continues to run causing an error as the channel no longer exists.

    python input:

    hello
    hello again

    tcl output:

    87.115.149.231 joined
    Got: hello
    Got: hello again
    Got:
    Client has disconnected.
    can not find channel named "sock5573b3ce5050"
    while executing
    "read $channel"
    (procedure "receive" line 8)
    invoked from within
    "receive sock5573b3ce5050"

    receive function:

    proc receive {channel} {
    if {[eof $channel]} {
    close $channel
    puts "Client has disconnected."
    }

    puts "Got: [read $channel]"
    flush $channel
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Shaun Kulesa on Mon Apr 10 20:51:21 2023
    Shaun Kulesa <[email protected]> wrote:
    I got it to work as it closes the socket connection but the receive
    function continues to run causing an error as the channel no longer
    exists.

    python input:

    hello
    hello again

    tcl output:

    87.115.149.231 joined
    Got: hello
    Got: hello again
    Got:
    Client has disconnected.
    can not find channel named "sock5573b3ce5050"
    while executing
    "read $channel"
    (procedure "receive" line 8)
    invoked from within
    "receive sock5573b3ce5050"

    receive function:

    proc receive {channel} {
    if {[eof $channel]} {
    close $channel
    puts "Client has disconnected."
    }

    puts "Got: [read $channel]"
    flush $channel
    }

    Move your 'eof' to after the read. The [eof] signal only arrives
    *after* you attempt to perform a read from the channel.

    This is also documented in the [eof] manpage:

    Returns 1 if an end of file condition occurred during the most
    recent input operation on channelId (such as gets), 0 otherwise.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Kulesa@21:1/5 to All on Mon Apr 10 14:19:33 2023
    Thank you for your explanations, it now works correctly.

    Also thank you to saitology9 for spending your time trying to help me in the beginning.

    87.115.149.231 joined
    Got: hello
    Got: hello2
    Got:
    Client has disconnected.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)