Search code examples
socketstcplispcommon-lispusocket

Read-line from socket-stream in lisp


I am working on a TCP client in lisp, and am having difficulties reading/printing the socket-stream correctly. When the client sends data to the server it should receive a response, and I need to write this to stdout. This works correctly, except I am having an issue where the response is printing twice. If I have multiple commands being sent, only the last one will be printed twice. Here is my code:

(defun socket-print (string socket)
    (write-line string (usocket:socket-stream socket))
    (force-output (usocket:socket-stream socket)))


(defun socket-read (socket)
    (write-line (read-line (usocket:socket-stream socket) nil)))


(defun mytest (command)
    (let ((socket (usocket:socket-connect _IP_ _PORT_)))
        (socket-print command socket)
        (socket-read socket)))

Solution

  • I don't think it's printing twice. I think it's printing (via write-line) once, and then write-line is returning the line, and the REPL is printing the return value. E.g., if you modify your mytest to return nil, I think you'll see the output that you're expecting:

    (defun mytest (command)
        (let ((socket (usocket:socket-connect _IP_ _PORT_)))
            (socket-print command socket)
            (socket-read socket)
            nil))
    

    This should print the line with write-line, and then return nil, and the REPL will print nil. Compare this with:

    CL-USER> (defun echo (line)
               (write-line line))
    ECHO
    CL-USER> (echo "hello")
    hello
    "hello"
    CL-USER> (progn
               (echo "hello")
               (echo "world"))
    hello
    world
    "world"
    CL-USER> (progn
               (echo "hello")
               (echo "world")
               nil)
    hello
    world
    NIL
    CL-USER> (progn
               (echo "hello")
               (echo "world")
               (values))
    hello
    world
    ; No value
    

    Also see: