3

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.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Heranort
  • 85
  • 4
  • 2
    Note that in Common Lisp IO can be buffered. Make sure that you always use `FINISH-OUTPUT` or `FORCE-OUTPUT` after the relevant output operations, if you want to see them actually being transferred. – Rainer Joswig Sep 26 '15 at 14:40
  • This is reasonable, but I'd like to say, after i run the client code, the server has no response. So I want to know is there any problem with the code above? Is anything i missed that prevent me from making a connect? – Heranort Sep 27 '15 at 02:08

1 Answers1

2

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.