Subject: [clisp-list] writing to a socket

From: Jeremy Doolin <[email-masked]>
Date: Wed Mar 13 16:00:02 2002

Hey,

I'm trying to write the contents of a file to a socket with a series of
formats.  After I'm done writing, I would like to immediately close the
socket (by the way, this is an HTTP server).  However, if I close it,
only one line will get written to the socket and the connection gets
closed.  If I don't close it, everything gets written to the socket, but
a browser will just hang there waiting for the end of the file.  

Here is what I'm doing (with some other stuff stripped out).

(let ((msock (socket-server 9876)))
   (loop
     do (let* ((ssock (socket-accept msock))
               (cc (read-line ssock)))
           ;some testing and stuff
               (let* ((od (open "file")))
                  (format ssock "Content-Length: ~D~%" (file-length od))
                  (format ssock "Content-Type: text/html~%~%")
                  ; read file loop
           (close ssock))))

Here is the output through a telnet session:

user@host >> telnet localhost 8383
Trying 127.0.0.1
Connected to localhost
Escape character is '^]'.
GET /index.html HTTP/1.0

Content-Length: 119Connection closed by foreign host.

Now, don't worry if you see something wrong with how the HTTP part
should be implemented, this is just a stub to see if I can get it to
write a file to the socket.

Can anyone set me straight here?

Oh, also, in the server I wrote in C, I fork()ed and did all my socket
writing in the child.  I would like to be able to do *something* like
that in mine.  I know there isn't a fork, but is there multiprocessing
of some kind?  

Jeremy Doolin
-- 
May all your disgraces be private

---

From: Paolo Amoroso <[email-masked]>
Date: Thu Mar 14 06:14:05 2002

> that in mine.  I know there isn't a fork, but is there multiprocessing

If you build CLISP with Unix bindings, you get access to LINUX:FORK. Sam
recently posted here the following example:

(defun mesg (&rest fmt-args)
  (format t "~&[~d] " (linux:getpid))
  (apply #'format t fmt-args))
(defun test-wait2 ()
  (let ((pid (linux:fork)))
    (cond ((= pid -1) (error "fork failed"))
	  ((/= pid 0)
           (mesg "Started child ~d~%" pid)
           (multiple-value-bind (childpid status) (linux:wait)
             (mesg "Child ~d has finished~%" childpid)
             (if (zerop (logand status #x7f))
                 (mesg "with exit code=~a~%" (linux:WEXITSTATUS status))
                 (mesg "Child bombed ~d / ~d~%" (linux:WTERMSIG status)
                       (linux:WEXITSTATUS status)))))
	  (t (sleep 1)          ; let dad go first
             (mesg "Hello, Pop (~d), I am ~d~%"
                   (linux:getppid) (linux:getpid))
             (linux:exit 37)))))
(test-wait2)

[17857] Started child 17858
[17858] Hello, Pop (17857), I am 17858
[17857] Child 17858 has finished
[17857] with exit code=37

The Common Lisp Cookbook includes an example with CMU CL.

Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://www.paoloamoroso.it/ency/README
[http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/]

---

From: Sam Steingold <[email-masked]>
Date: Thu Mar 14 07:41:05 2002

> * In message <1016063971.1271.59.camel@zeus>
> * On the subject of "[clisp-list] writing to a socket"
> * Sent on 13 Mar 2002 18:59:30 -0500
> * Honorable Jeremy Doolin <[email-masked]> writes:
>
> I'm trying to write the contents of a file to a socket with a series
> of formats.  After I'm done writing, I would like to immediately close
> the socket (by the way, this is an HTTP server).  However, if I close
> it, only one line will get written to the socket and the connection
> gets closed.  If I don't close it, everything gets written to the
> socket, but a browser will just hang there waiting for the end of the
> file.
> 

this is very strange.
I do not observe this:

[1]> (setq s (socket-server 12345))
#<SOCKET-SERVER 0.0.0.0:12345>
[2]> (setq o (socket-accept s))
#<IO UNBUFFERED SOCKET-STREAM CHARACTER 0.0.0.0:12345>
[3]> (read-line o)
"foo bar!" ;
NIL
[4]> (format o "zot~%")
NIL
[5]> (with-open-file (f "/proc/cpuinfo") (loop for l = (read-line f nil nil) while l do (write-line l o)))
NIL
[6]> (close o)
T
[7]> 

$ telnet localhost 12345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
foo bar!
zot
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 5
model           : 8
model name      : Mobile Pentium MMX
stepping        : 1
cpu MHz         : 199.995
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : yes
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr mce cx8 mmx
bogomips        : 398.13

Connection closed by foreign host.
$

maybe you could send us some actual code?
Please do not send megabytes of intricate server implementations -
strip it to a simple example as mine above.
or, better yet, debug it yourself? :-)

I assume you are using 2.28 (not that it should matter - these things
have been working just fine since forever)

PS I recommend using `with-open-file' instead of `open' and
`with-open-stream+socket-accept/socket-connect' instead of bare
`socket-accept/socket-connect'.

> that in mine.  I know there isn't a fork, but is there multiprocessing

you shouldn't need anything like that here.
CLISP INSPECT works as an HTTP server just fine.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
Daddy, why doesn't this magnet pick up this floppy disk?