草庐IT

sockets - 通过 LISP USOCKET 接收数据

coder 2023-09-17 原文

我正在尝试通过 USOCKET 发送数据.当数据到达服务器时,服务器应该回复。但是,stream-read(定义如下)仅在数据与它发送的原始数据回显时才返回数据。例如,如果我发送 hello 并且服务器回复相同的数据,hello,然后 stream-read 返回,但如果服务器回复对于 histream-read 不会返回,直到服务器发送它接收到的确切缓冲区。

这是代码:(我在网上找到了大部分代码。)

;; 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))

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

...

void session(socket_ptr sock)
{
   try
   {    
    for (;;)
    {
      char data[max_length];

      boost::system::error_code error;
      size_t length = sock->read_some(boost::asio::buffer(data), error);
      if (error == boost::asio::error::eof)
      break; // Connection closed cleanly by peer.
      else if (error)
      throw boost::system::system_error(error); // Some other error.


    std::vector<char> v(data,data+length);
            std::string theStr;

        for(unsigned int i=0;i<v.size();i++)
        {
        if(v[i]<32 || v[i]>=0x7f);//Remove non-ascii char
        else theStr.insert(theStr.end(),v[i]);
    }
    std::cout<<"|"<<theStr<<"|"<<std::endl;

    boost::asio::write(*sock, boost::asio::buffer(data, length)); //works
    boost::asio::write(*sock, boost::asio::buffer("some", 4));  //doesn't work
}
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception in thread: " << e.what() << "\n";
  }
}
   ...

最佳答案

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

  1. 从客户端到服务器的每次调用都使用相同的套接字。如果服务器没有预料到这一点,它的行为将不会如您所愿。

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

  3. 忠告: (a) my-stream 实际上是套接字,不是流; (b) 我鼓励您使用 Quicklisp 管理外部库.

这是一个完整的工作示例。这是在 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

关于sockets - 通过 LISP USOCKET 接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17257567/

有关sockets - 通过 LISP USOCKET 接收数据的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  5. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  6. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  7. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  8. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  9. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  10. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

随机推荐