sockets networking tcp common-lisp usocket

sockets - Recibir datos a través de LISP USOCKET



networking tcp (1)

Sin ver el código de su servidor es difícil responder sin un poco de especulación. Pero:

  1. Utiliza el mismo socket para cada llamada del cliente al servidor. Si el servidor no espera eso, no se comportará como lo desea.

  2. Su definición de llamadas de stream-read de stream-read socket-listen . ¿ usocket:socket-listen decir usocket:socket-listen ? Esta es una función del lado del servidor (y toma diferentes argumentos). Probablemente no estoy viendo el código exacto que estaba ejecutando.

  3. Notas de asesoramiento: (a) my-stream es en realidad un socket, no un stream; (b) Lo animo a administrar bibliotecas externas usando Quicklisp .

Aquí hay un ejemplo completo de trabajo. Esto está en LispWorks; He utilizado LW internals para el servidor para dejar absolutamente claro cuál es el servidor y cuál es el cliente.

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

Si aún tiene problemas, publique nuevamente con la fuente de su servidor y su stream-read real.

Estoy tratando de enviar datos a través de USOCKET . Cuando los datos llegan al servidor, el servidor debe responder de nuevo. Sin embargo, stream-read (como se define a continuación) solo devuelve los datos cuando se repiten con los datos originales que envió. Por ejemplo, si envío hello y el servidor responde con la misma información, hello , luego stream-read , pero si el servidor responde con hi , stream-read no regresa hasta que el servidor envía el buffer exacto que recibió.

Aquí está el código: (Encontré la mayor parte en línea).

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

En cuanto al servidor, estoy usando una versión ligeramente modificada del ejemplo del servidor de bloqueo de refuerzo. (c ++) El código completo se puede encontrar aquí: 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"; } } ...