Search code examples
socketscommon-lispusocket

How to use usocket to create a connection? (common lisp)


I'm trying to use socket in lisp to create a connection. Using sbcl, i found "usocket" available. But I failed to sending strings between the server and client. Here's the code:

Server:

(ql:quickload "usocket")
(use-package 'usocket)
(defun default-tcp-handler (stream) ; null
  (declare (type stream stream))
  (terpri stream))
(defparameter *us* (socket-server "127.0.0.1" 4547 #'default-tcp-handler))
(defparameter *s* (socket-accept *us*))
(defparameter *ss* (usocket:socket-stream *s*))

Client:

(ql:quickload "usocket")
(use-package 'usocket)
(defparameter *us* (socket-connect "127.0.0.1" 4547))
(defparameter *st* (usocket:socket-stream *us*))

I ran the server code first, it freezes. Then I ran the client code. But the server seemed to be no response. I tried to format a string into the st stream:

(format *st* "hello, server")

But it returns nil.

How can i solve the problem?? Thanks a lot.


Solution

  • I tried your code and there were no errors, so everything seemed to be all right with the connection. However, if you only write to streams without reading (not to mention flushing the output), the connection has no way to manifest itself. Here is a modified version where the server reads a single line from the socket:

    ;;; server
    (ql:quickload "usocket")
    (use-package :usocket)
    (defun default-tcp-handler (stream)
      (declare (type stream stream))
      (format t "~A~%" (read-line stream))
      (finish-output))
    (defparameter *us* (socket-server "127.0.0.1" 4547 #'default-tcp-handler))
    
    ;;; client
    (ql:quickload "usocket")
    (use-package :usocket)
    (defparameter *us* (socket-connect "127.0.0.1" 4547))
    (defparameter *st* (socket-stream *us*))
    (write-line "hello server" *st*)
    (finish-output *st*)
    

    In your case format returned nil, because it always returns nil except format nil. The server hangs because it starts listening. If you don't want that, you'll have to work with multiple threads.