Receiving data through LISP USOCKET - sockets

I'm trying to send data over USOCKET. When the data reaches the server, the server should reply back. However, stream-read (as defined below) only returns the data when it's echoed back with the original data it sent. For example, if I send hello and the server replies with the same data, hello, then stream-read returns, but if the server replies with hi, stream-read doesn't return until the server sends the exact buffer it received.
Here's the code: (I've found most of it online.)
;; 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))
As for the server, I'm using a slightly modified version of the boost blocking server example. (c++) The full code can be found here: 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";
}
}
...

Without seeing the code for your server it's hard to answer without a bit of speculation. But:
You use the same socket for each call from the client to the server. If the server isn't expecting that, it won't behave as you want it to.
Your definition of stream-read calls socket-listen. Did you mean usocket:socket-listen? This is a server-side function (and takes different arguments). I'm probably not looking at the exact code you were running.
Advisory notes: (a) my-stream is actually a socket, not a stream; (b) I encourage you to manage external libraries using Quicklisp.
Here's a full working example. This is on LispWorks; I've used LW internals for the server to make it utterly clear which is server and which is client.
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
If you're still having difficulties, post again with source for your server and your actual stream-read.

Related

Why isn't my macro functioning in the same way as handwritten code?

So I have 2 router functions for learning to work with clack in common lisp. One is written without macros, and the other is written with macros that expand to match the first function, but only the non-macro version is working. The code below has (:use :trivia) from (ql:quickload 'trivia).
This one is written without any macros, and works:
(defun router (env)
(match env
((guard (property :path-info path)
(equalp "/" path))
(home env))
((guard (property :path-info path)
(equalp "/live/clicked" path))
(live-clicked env))
((property :path-info path)
`(404 nil (,(format nil "404 page not found"))))))
I decided I didn't like those guard clauses taking up so much space in the function definition, so I rewrote the function:
(defun router (env)
(match env
(route "/" (home env))
(route "/live/clicked" (live-clicked env))
((property :path-info path)
`(404 nil (,(format nil "404 page not found"))))))
route is defined as so:
(defmacro route (valid-path &body body)
(let ((path (gensym)))
`((guard (property :path-info ,path)
(equalp ,valid-path ,path))
,#body)))
With this new router function and macro, the function is always short-circuiting on the first clause. When macroexpanding the 2 (route ...) clauses, I receive this output, matching the function I wrote:
* `(defun router (env)
(match env
,(macroexpand '(route "/" (home env)))
,(macroexpand '(route "/live/clicked" (live-clicked env)))
((property :path-info path)
`(404 nil (,(format nil "404")))))))
(DEFUN ROUTER (ENV)
(MATCH ENV
((GUARD (PROPERTY :PATH-INFO #:G120) (EQUALP "/" #:G120)) (HOME ENV))
((GUARD (PROPERTY :PATH-INFO #:G121) (EQUALP "/live/clicked" #:G121)) (LIVE-CLICKED ENV))
((PROPERTY :PATH-INFO PATH) `(404 NIL (,(FORMAT NIL "404")))))
(home env) and (live-clicked env) are functions that return something similar to (backquote (200 nil (,(*form generating html*)))). env is the state of the web request, but in this instance it only needs to be (list :path-info "/live/clicked")
First of all, macroexpand should be
used for interactive debugging rather than in production code.
Its use inside defun (almost) never makes sense.
Second, to understand your second router, you should macroexpand its body
rather than the defun, i.e.,
(macroexpand '(match env
(route "/" (home env))
(route "/live/clicked" (live-clicked env))
((property :path-info path)
`(404 nil (,(format nil "404"))))))
You will see that route is not expanded because it is not in a "function position".
What you need to expand your route before match is expanded, i.e., you probably want a
wrapper around match (I removed gensym because you indicated in the comments that it is really
not necessary):
(defmacro my-match (what &body clauses)
(labels ((handle-clause (clause)
(if (eq (car clause) 'route)
(apply #'route (rest clause))
clause))
(route (valid-path &rest body)
`((guard (property :path-info path)
(equalp ,valid-path path))
,#body)))
`(match ,what ,#(mapcar #'handle-clause clauses))))
and then
(defun router (env)
(my-match env
(route "/" (home env))
(route "/live/clicked" (live-clicked env))
((property :path-info path)
`(404 nil (,(format nil "404 page not found"))))))
Testing:
(macroexpand '(my-match env
(route "/" (home env))
(route "/live/clicked" (live-clicked env))
((property :path-info path)
`(404 nil (,(format nil "404"))))))
==>
(MATCH ENV ((GUARD (PROPERTY :PATH-INFO PATH) (EQUALP "/" PATH)) (HOME ENV))
((GUARD (PROPERTY :PATH-INFO PATH) (EQUALP "/live/clicked" PATH))
(LIVE-CLICKED ENV))
((PROPERTY :PATH-INFO PATH) `(404 NIL (,(FORMAT NIL "404")))))
T
The pattern matcher you are using, Trivia, has a defpattern macro. That's what you must use to define a macro against the pattern language itself, rather than defmacro.

Generating inline javascript with cl-who, parenscript and hunchentoot

I'm trying to generate inline javascript, but I have to put the parenscript code inside (:script) and (str) tags using cl-who. ps, ps*, ps-inline and ps-inline* don't seem to make much difference to the generated js.
Is the usual way to write a macro to avoid code duplication, or is there a better way?
Here's my program:
(in-package #:ps-test)
(defmacro standard-page ((&key title) &body body)
`(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
(:html
:lang "en"
(:head
(:meta :http-equiv "Content-Type"
:content "text/html;charset=utf-8")
(:title ,title)
(:link :type "text/css"
:rel "stylesheet"
:href "/style.css"))
(:body
,#body))))
(defun main ()
(with-html-output (*standard-output* nil :indent t :prologue nil)
(standard-page (:title "Parenscript test")
(:div (str "Hello worldzors"))
(:script :type "text/javascript"
(str (ps (alert "Hello world as well")))))))
(define-easy-handler (docroot :uri "/") ()
(main))
(defun start-ps-test ()
(setf (html-mode) :html5)
(setf *js-string-delimiter* #\")
(start (make-instance 'hunchentoot:easy-acceptor :port 8080)))
(defun stop-ps-test ()
(stop *server*))
(defvar *server* (start-ps-test))
Macros are fine in this use case.
The trick is that macros are expanded in a specific order. Say
you define a js macro: when macroexpansion encounters
with-html-output, the inner call to your macros (js (alert "Ho Ho Ho")) looks like a function call, and is left as-is in the generated
code. If your js macro then expands into (:script ...), then the system will complain that :script is an unknown function (assuming you
didn't actually name a function like that). You should emit an
enclosing (who:htm ...) expression to interpret the code using
CL-WHO's code walker.
(defmacro js (code)
`(who:htm
(:script :type "text/javascript" (who:str (ps:ps ,code)))))
This only works in the context of an enclosing with-html-output.
For inline Javascript, you don't want to have a <script> tag around it,
and you can generally simply use ps-inline:
(who:with-html-output (*standard-output*)
(:a :href (ps:ps-inline (void 0))
"A link where the usual HREF behavior is canceled."))
;; prints:
;;
;; <a href='javascript:void(0)'>A link where the usual HREF behavior is canceled.</a>
But feel free to use a macro if you often do the same thing:
(defmacro link (&body body)
`(who:htm (:a :href #.(ps:ps-inline (void 0)) ,#body)))
(who:with-html-output (*standard-output*) (link "Link"))
;; prints:
;;
;; <a href='javascript:void(0)'>Link</a>

ring redirect after login

(ns ...
(:require [ring.util.response :refer [ response redirect]))
My original code be-all-like
(-> (response "You are now logged in! communist party time!")
(assoc :session new-session)
(assoc :headers {"Content-Type" "text/html"}))
Which worked well, but the user still has to navigate elsewhere manually.
Trying to use http://ring-clojure.github.io/ring/ring.util.response.html#var-redirect
(-> (redirect requri)
(assoc :session new-session)
(assoc :headers {"Content-Type" "text/html"}))
doesn't do anything (aside from returning a blank page).
How can I achieve a redirect to a known uri using ring?
response is return a body.
you code is (response requri),but the param of the funtion reponse is html body,not a uri,you can use the this function
like this
(ns foo
(:require [ring.util.response :as response]))
(def requi "/")
(-> (response/redirect requri)
(assoc :session new-session)
(assoc :headers {"Content-Type" "text/html"}))
ps: if you are writing a web site.the lib-noir is a good way to control the session and other.
ipaomian has the answer.
Wanted to share a nice redirect hack:
(ns foo
(:require [ring.util.response :as response]))
(defn redirect
"Like ring.util.response/redirect but also accepts key value pairs
to assoc to response."
[url & kvs]
(let [resp (response/redirect url)]
(if kvs (apply assoc resp kvs) resp)))
(redirect "/" :session new-session :headers {"Content-Type" "text/html"})
ipaomian is right however mine worked by removing the headers. This is my code:
(:require
[ring.util.response :refer [redirect]])
(defn set-user! [id {session :session}]
(-> (redirect "/home")
(assoc :session (assoc session :user id))))

Emacs: how to stop jedi?

I regularly use jedi.el, it works great. But I don't know how to stop it !
I manually call it with jedi:setup (which turns jedi-mode on) and try to stop it with jedi-mode but it has no effect. It is unconvenient and it gets in the way with yasnippet.
Do you have a solution ? Thanks.
config: emacs24 and latest jedi.el version from melpa. Result of jedi:show-setup-info:
;; Emacs Lisp version:
(:emacs-version "24.3.1" :jedi-version "0.2.0alpha2" :python-environment-version "0.0.2alpha0")
;; Python version:
((:version "2.7.3 (default, Feb 27 2014, 19:58:35) \n[GCC 4.6.3]" :name "sys" :file nil)
(:version "0.7.0" :name "jedi" :file "/usr/local/lib/python2.7/dist-packages/jedi/__init__.pyc")
(:version "0.0.5" :name "epc" :file "/usr/local/lib/python2.7/dist-packages/epc/__init__.pyc")
(:version "0.0.3" :name "sexpdata" :file "/usr/local/lib/python2.7/dist-packages/sexpdata.pyc"))
;; Command line:
(:virtualenv "/usr/bin/virtualenv" :virtualenv-version "1.7.1.2\n")
;; Customization:
((jedi:complete-on-dot)
(jedi:doc-display-buffer . display-buffer)
(jedi:doc-hook view-mode)
(jedi:doc-mode . rst-mode)
(jedi:environment-root)
(jedi:environment-virtualenv)
(jedi:get-in-function-call-delay . 1000)
(jedi:get-in-function-call-timeout . 3000)
(jedi:goto-definition-config
(nil nil nil)
(t nil nil)
(nil definition nil)
(t definition nil)
(nil nil t)
(t nil t)
(nil definition t)
(t definition t))
(jedi:goto-definition-marker-ring-length . 16)
(jedi:imenu-create-index-function . jedi:create-nested-imenu-index)
(jedi:import-python-el-settings . t)
(jedi:install-imenu)
(jedi:install-python-jedi-dev-command "pip" "install" "--upgrade" "git+https://github.com/davidhalter/jedi.git#dev#egg=jedi")
(jedi:key-complete .
[C-tab])
(jedi:key-goto-definition .
[67108910])
(jedi:key-goto-definition-pop-marker .
[67108908])
(jedi:key-related-names . "r")
(jedi:key-show-doc . "d")
(jedi:server-args)
(jedi:server-command "python" "/home/vdardelx/.emacs.d/elpa/jedi-20140321.1323/jediepcserver.py")
(jedi:setup-keys)
(jedi:tooltip-method pos-tip popup)
(jedi:use-shortcuts)
(python-environment-default-root-name . "default")
(python-environment-directory . "~/.emacs.d/.python-environments")
(python-environment-virtualenv "virtualenv" "--system-site-packages" "--quiet"))
What aspect is conflicting with yasnippet? Is it the use of autocomplete-mode? (which seems to be the other broad consequence of running jedi:setup, and which isn't turned off again when jedi-mode is disabled.)
M-x autocomplete-mode will toggle that off again, or call (autocomplete-mode -1) in code.
You could write a function to disable both modes together, and call that to turn jedi off. A more robust approach would remember the state of autocomplete-mode at the time jedi was enabled in order to restore it afterwards, but it sounds like that's not critical in your case.

Elisp help. Why does the following snippet fail?

I'm trying to write a little script that notifies me when someone talks to me in erc. So I need to write a funcion that recieves what I presume are two strings, nick and msg so I can hook it. But my test function fails. I have tested growl-notify and the format s-expresions and they work fine but I cant get test to work. I have no idea why is it failing. Any pointers?
(defun growl-notify (&key message)
"Use growl for notifications"
(start-process "growlnotify" "growlnotifications" "growlnotify" "-m " message))
(defun test (nick msg)
(growlnotify :message (format "%s: %s" nick msg)))
(test "Ppop" "something")
It gives the following backtrack, hope it helps.
Debugger entered--Lisp error: (void-function growlnotify)
(growlnotify :message (format "%s: %s" nick msg))
test("oi" "poi")
eval((test "oi" "poi") nil)
eval-last-sexp-1(t)
eval-last-sexp(t)
eval-print-last-sexp()
call-interactively(eval-print-last-sexp nil nil)
recursive-edit()
debug(error (wrong-number-of-arguments (lambda (&key message) "Use growl for notifications" (start-process "growlnotify" "growlnotifications" "growlnotify" "-m " message)) 3))
The error message is Debugger entered--Lisp error: (void-function growlnotify), which tells you that growlnotify isn't defined as a function.
If you look at your code, you'll see that you defined it like this: (defun growl-notify (&key message), which defines a function called growl-notify. A simple typo.