列表中的双向插座 [英] Bidirectional socket in List

查看:96
本文介绍了列表中的双向插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过使用TCP/IP套接字(在Linux系统中具有sbcl和usocket库)将Lisp脚本与另一个程序进行通信.

I'm trying to communicate from a Lisp script to another program by using TCP/IP sockets (with sbcl and the usocket library in a Linux system).

到目前为止,我已经获得了以下代码:

So far I got this code:

(require 'asdf)
(require 'usocket)

(defun start-client ()
    (   usocket:with-client-socket
    (socket stream "0.0.0.0" 30000)


    (loop for x in '("1~%" "2~%" "3~%" "4~%" "5~%") do 
        (format stream x)
        (force-output stream)
        (sleep 1)
        ;;(format t "~A~%" (read-line stream))
    )
    )
)
(start-client)

除了注释行之外,该代码运行良好:

The code works well with the exception of the commented line:

(format t "~A~%" (read-line stream))

因此,我能够从另一个套接字(另一个程序)发送和接收消息1,2,3 ...,并将消息从另一个程序发送回lisp.但是,当我取消注释以从lisp读取消息的行时,上面的代码似乎停止并永远等待.

So I'm able to send and receive the messages 1,2,3 ... from the other socket (another program) and send messages back from the other program to lisp. However, when I uncomment the line to read the messages from lisp, the above code seems to stop and wait forever.

推荐答案

在不知道服务器的情况下很难说出问题所在.也许它永远不会终止线路?

It is difficult to tell what your problem is, without knowing the server. Maybe it never terminates the line?

这是一个小示例,使用线程隔离客户端和服务器:

Here is a little demo, using threads to isolate client and server:

(in-package #:cl-user)

(eval-when (:compile-toplevel :load-toplevel :execute)
  (ql:quickload '("usocket" "bordeaux-threads")))

(defpackage #:usocket-demo
  (:use #:cl))

(in-package #:usocket-demo)

(defun serve (port)
  "Starts a socket server to answer a single request."
  (usocket:with-socket-listener (server-socket "0.0.0.0" port
                                               :reuse-address t)
    (let* ((stream-socket (usocket:socket-accept server-socket))
           (server-stream (usocket:socket-stream stream-socket))
           (request (read-line server-stream)))           ; read
      (format t "S> serving…~%")
      (format server-stream "Hello, ~a!~%" request)       ; write
      (finish-output server-stream))))

(defun cly (port)
  "Makes a single request to a server and prints the answer."
  (usocket:with-client-socket (client-socket client-stream "0.0.0.0" port)
    (format client-stream "Issa me!~%")                   ; write
    (finish-output client-stream)
    (let ((response (read-line client-stream)))           ; read
      (format t "C> I got a response: ~a~%" response))))

(defun run-demo ()
  (let ((bt:*default-special-bindings*
          `((*standard-output* . ,*standard-output*))))
    (bt:make-thread (lambda ()
                      (serve 13575))
                    :name "Server")
    (bt:make-thread (lambda ()
                      (cly 13575))
                    :name "Client")
    (values)))

bt:*default-special-bindings的绑定是必需的,这样线程才能为演示消息看到相同的输出流.

The binding of bt:*default-special-bindings is necessary so that the threads see the same output stream for the demo messages.

如您所见,客户端和服务器都有一个可以读取和写入的流.

As you see, both client and server have a stream that they can read from and write to.

这篇关于列表中的双向插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆