通过LISP USOCKET接收数据

时间:2013-06-23 03:49:09

标签: sockets networking tcp common-lisp usocket

我正在尝试通过USOCKET发送数据。当数据到达服务器时,服务器应该回复。但是,stream-read(如下所述)仅在数据与其发送的原始数据一起回显时返回数据。例如,如果我发送hello并且服务器使用相同的数据hello回复,则stream-read会返回,但如果服务器回复hi,则{{1}在服务器发送收到的确切缓冲区之前,它不会返回。

以下是代码:(我在网上找到了大部分内容。)

stream-read

至于服务器,我正在使用一个略微修改版本的boost阻塞服务器示例。 (c ++)完整的代码可以在这里找到:http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/echo/blocking_tcp_echo_server.cpp

;; Load USocket
(load #P"/usr/share/common-lisp/source/cl-asdf/asdf.lisp")      
(asdf:operate 'asdf:load-op :usocket)

(defun stream-read (stream)
  (socket-listen (usocket:socket-stream stream)))

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

;; Define a stream
(defparameter my-stream
  (usocket:socket-connect "127.0.0.1" 6003))

;; Use the stream
(stream-print "random" my-stream)
(print (stream-read my-stream))

1 个答案:

答案 0 :(得分:11)

如果没有看到服务器的代码,如果没有一点猜测就很难回答。但是:

  1. 对于从客户端到服务器的每次调用,都使用相同的套接字。如果服务器不期望它,它将不会按照您的意愿运行。

  2. 您对stream-read来电socket-listen的定义。你是说usocket:socket-listen吗?这是一个服务器端函数(并采用不同的参数)。我可能不会查看您运行的确切代码。

  3. 咨询说明:(a)my-stream实际上是一个套接字,而不是一个流; (b)我鼓励您使用Quicklisp管理外部库。

  4. 这是一个完整的工作示例。这是在LispWorks上;我已经使用LW内部服务器使服务器完全清楚哪个是服务器,哪个是客户端。

    CL-USER 1 > (ql:quickload :usocket)
    To load "usocket":
      Load 1 ASDF system:
        usocket
    ; Loading "usocket"
    
    (:USOCKET)
    
    CL-USER 2 > (comm:start-up-server
                 :service 6003
                 :function (lambda (handle)
                             (let* ((stream (make-instance 'comm:socket-stream
                                                           :socket handle
                                                           :direction :io
                                                           :element-type 'base-char))
                                    (line (read-line stream)))
                               (format stream "Hello: ~a~%" line)
                               (force-output stream))))
    #<MP:PROCESS Name "6003 server" Priority 85000000 State "Running">
    
    CL-USER 3 > (defun socket-read (socket)
                  (read-line (usocket:socket-stream socket)))
    SOCKET-READ
    
    CL-USER 4 > (defun socket-print (string socket)
                  (write-line string (usocket:socket-stream socket))
                  (force-output (usocket:socket-stream socket)))
    SOCKET-PRINT
    
    CL-USER 5 > (defun test (thing)
                  (let ((socket (usocket:socket-connect "127.0.0.1" 6003)))
                    (socket-print thing socket)
                    (socket-read socket)))
    TEST
    
    CL-USER 6 > (test "Buttered toast")
    "Hello: Buttered toast"
    NIL
    
    CL-USER 7 > (test "A nice cup of tea")
    "Hello: A nice cup of tea"
    NIL
    

    如果您仍然遇到问题,请使用您的服务器的来源和实际的stream-read重新发布。