Lisp HUG Maillist Archive

Lispworks and UDP sockets

Hello,

Can anyone recommend the best way to do UDP sockets in Lispworks?  I'm looking for a solution that works on linux, but windows compatibility would be a plus.

Thanks,

AnthonyF

Re: Lispworks and UDP sockets

I came across a c.l.l post[1] that referenced some UDP-in-LispWorks-on-Linux 
code[2]. I too need UDP/LW/Win32, so I plan to port this code (i.e. its C glue) 
to Windows.

HTH,

John :^P

[1] http://article.gmane.org/gmane.lisp.lispworks.general/2278
[2] http://www.cartan.de/cludp.tar.gz

Anthony Fairchild wrote:
> Hello,
> 
> Can anyone recommend the best way to do UDP sockets in Lispworks?  I'm 
> looking for a solution that works on linux, but windows compatibility 
> would be a plus.
> 
> Thanks,
> 
> AnthonyF

-- 
John Pallister
john@synchromesh.com


Re: Lispworks and UDP sockets


On 4/28/07, John Pallister <john@synchromesh.com> wrote:
I came across a c.l.l post[1] that referenced some UDP-in-LispWorks-on-Linux
code[2]. I too need UDP/LW/Win32, so I plan to port this code (i.e. its C glue)
to Windows.

HTH,

John :^P

[1] http://article.gmane.org/gmane.lisp.lispworks.general/2278
[2] http://www.cartan.de/cludp.tar.gz

Thank you, I think this will work well for what I want to do!
 

Re: Lispworks and UDP sockets

Here is a quick and dirty hach which I used once on windows. It should be easy to tweak it for linux if it doesn't work as is.
 
Marc
 
(fli:define-c-typedef (socket (:foreign-name "SOCKET"))
                      (:unsigned :int))
 
(fli:define-c-struct (in-addr (:foreign-name "in_addr"))
                     (s-addr (:unsigned :long)))
 
(fli:define-c-struct (sockaddr-in (:foreign-name "sockaddr_in"))
                     (sin-family :short)
                     (sin-port (:unsigned :short))
                     (sin-addr (:unsigned :long))
                     (sin-zero (:c-array :char 8)))
 
(fli:define-c-typedef :udp-buffer (:c-array (:unsigned :char) 64))
 
(fli:define-foreign-function (socket "socket" :source)
                             ((af :int) (type :int) (protocol :int))
                             :result-type socket
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(fli:define-c-struct (sockaddr
                      (:foreign-name "sockaddr")
                      (:forward-reference t)))
 
(fli:define-foreign-function (bind "bind" :source)
                             ((s socket)
                              (name (:pointer (:struct sockaddr-in)))
                              (namelen :int))
                             :result-type :int
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(fli:define-foreign-function (set-sock-opt "setsockopt" :source)
                             ((s socket)
                              (level :int)
                              (optname :int)
                              (optval (:pointer :char))
                              (optlen :int))
                             :result-type :int
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(fli:define-foreign-function (send-to "sendto" :source)
                             ((s socket)
                              (buf (:pointer :char))
                              (len :int)
                              (flags :int)
                              (to (:pointer (:struct sockaddr)))
                              (tolen :int))
                             :result-type :int
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(fli:define-foreign-function (recv-from "recvfrom" :source)
                             ((s socket)
                              (buf :pointer)
                              (len :int)
                              (flags :int)
                              (from (:pointer (:struct sockaddr-in)))
                              (fromlen (:pointer :int)))
                             :result-type :int
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(fli:define-foreign-function (close-socket "closesocket" :source)
                             ((s socket))
                             :result-type :int
                             :language :ansi-c
                             :calling-convention :cdecl)
 
(defconstant AF_INET         2)
(defconstant SOCK_DGRAM      2)
(defconstant IPPROTO_UDP    17)
(defconstant INADDR_ANY    #x00000000)
 
(defvar *udp-socket* nil)
(defvar *udp-buffer* nil)
 
(defun start-udp-listener ()
  (unless *udp-socket*
    (setf *udp-socket* (socket AF_INET SOCK_DGRAM IPPROTO_UDP))
    (setf *udp-buffer* (fli:allocate-foreign-object :type '(:c-array (:unsigned :char) 100)))
    (fli:with-dynamic-foreign-objects ()
      (let ((recv-addr (fli:allocate-dynamic-foreign-object :type 'sockaddr-in)))
        (setf (fli:foreign-slot-value recv-addr 'sin-family) AF_INET
              (fli:foreign-slot-value recv-addr 'sin-port) #x8913 ;5001
              (fli:foreign-slot-value recv-addr 'sin-addr) INADDR_ANY)
        (bind *udp-socket* recv-addr (fli:size-of 'sockaddr-in)))))
  *udp-socket*)
 
(defun read-udp-socket ()
  (when *udp-socket*
    (fli:with-dynamic-foreign-objects ()
      (let* ((sender-addr (fli:allocate-dynamic-foreign-object :type 'sockaddr-in))
             (addr-size (fli:allocate-dynamic-foreign-object
                         :type :int :initial-element (fli:size-of 'sockaddr-in)))
             (nb-read (recv-from *udp-socket* *udp-buffer* 100 0 sender-addr addr-size)))
        (values
         (loop for i from 0 below nb-read collect (fli:foreign-aref *udp-buffer* i))
         (fli:foreign-slot-value sender-addr 'sin-port)
         (fli:foreign-slot-value sender-addr 'sin-addr))))))
 
(defun stop-udp-listener ()
  (when *udp-socket*
    (close-socket *udp-socket*)
    (setf *udp-socket* nil)))
 
 
Updated at: 2020-12-10 08:46 UTC