2013-06-23 22 views
5

Tôi đang cố gắng gửi dữ liệu qua số USOCKET. Khi dữ liệu đến máy chủ, máy chủ sẽ trả lời lại. Tuy nhiên, stream-read (như được định nghĩa bên dưới) chỉ trả về dữ liệu khi dữ liệu được lặp lại với dữ liệu gốc được gửi. Ví dụ, nếu tôi gửi hello và máy chủ trả lời với cùng một dữ liệu, hello, thì stream-read trả về, nhưng nếu máy chủ trả lời với hi, stream-read không trở lại cho đến khi máy chủ gửi bộ đệm chính xác mà nó nhận được.Nhận dữ liệu qua LISP USOCKET

Dưới đây là đoạn code: (Tôi đã tìm thấy hầu hết nó trực tuyến.)

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

Đối với các máy chủ, tôi đang sử dụng một phiên bản sửa đổi nhẹ của tăng chặn dụ máy chủ. (C++) Mã đầy đủ có thể được tìm thấy ở đây: 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"; 
    } 
} 
    ... 

Trả lời

11

Nếu không nhìn thấy mã cho máy chủ của bạn thật khó để trả lời mà không một chút suy đoán. Nhưng:

  1. Bạn sử dụng cùng một ổ cắm cho mỗi cuộc gọi từ máy khách đến máy chủ. Nếu máy chủ không mong đợi điều đó, nó sẽ không hoạt động như bạn muốn.

  2. Định nghĩa của bạn về stream-read gọi socket-listen. Ý của bạn là usocket:socket-listen? Đây là một chức năng phía máy chủ (và có các đối số khác nhau). Tôi có lẽ không nhìn vào mã chính xác mà bạn đang chạy.

  3. Ghi chú cố vấn: (a) my-stream thực sự là một ổ cắm chứ không phải là luồng; (b) Tôi khuyến khích bạn quản lý các thư viện bên ngoài bằng cách sử dụng Quicklisp.

Dưới đây là ví dụ làm việc đầy đủ. Đây là trên LispWorks; Tôi đã sử dụng nội bộ LW cho máy chủ để làm cho nó hoàn toàn rõ ràng đó là máy chủ và đó là khách hàng.

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 

Nếu bạn vẫn gặp khó khăn, hãy đăng lại với nguồn cho máy chủ và stream-read thực tế của bạn.

+0

Cảm ơn, tôi đã thêm mã máy chủ vào bài đăng chính. –

+0

Hình như máy chủ là vấn đề, thay thế nó bằng máy chủ echo C++ thực tế và mọi thứ hoạt động! http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/practical/ Ngoài ra, cảm ơn chức năng đọc ổ cắm, giờ đây nó đọc chính xác. –