trivial p2p in newLISP

Started by frontera000, August 22, 2006, 11:09:24 AM

Previous topic - Next topic

frontera000

Quote
; a trivial P2P file sharing program written in newLISP for demo purpose

;

;  based on ideas from http://www.freedom-to-tinker.com/tinyp2p.html">http://www.freedom-to-tinker.com/tinyp2p.html

; and http://ansuz.sooke.bc.ca/software/molester/">http://ansuz.sooke.bc.ca/software/molester/ and

; http://ansuz.sooke.bc.ca/software/molester/2005010301.php">http://ansuz.sooke.bc.ca/software/moles ... 010301.php">http://ansuz.sooke.bc.ca/software/molester/2005010301.php

;

; command reference

; i/ advertise presence of your node to the peer

; g<filename>/ requests a file

; f<message> forward to peers

; h/ gets list of all peers

;

; used internally

; e<filename>/ expect a file

; x  sent after receiving a file to make sure

;

; the program below is a toy, not a serious p2p program.

;

; differences from original mole-ster:

; use of 'x' -- to allow data receipt on receiving side when file is sent

; data is read in 8k chunks at a time.  this is to avoid having to read

; the entire file into a buffer before writing. it allows larger files to be

; transferred.

;

; more more information refer to the original mole-ster web sites.

;



(context 'P2P)



(constant 'SIGINT 2)

(define (interrupted)

  (println "interruted by user!")

  (exit))



(signal SIGINT interrupted)



(set 'my-address "")

(set 'my-password "")

(set 'peers '())



(define (get-addr addr-and-port)  (regex "(.*):(.*)" addr-and-port)  $1)

(define (get-port addr-and-port)  (regex "(.*):(.*)" addr-and-port)  (integer $2))



(define (op-send dest-addr source-addr filename data)

  (if (set 'socket (net-connect (get-addr dest-addr) (get-port dest-addr)))

      (begin

         (net-send socket (format "%s %s %s/" my-password source-addr filename))

         (net-send socket data )

         (if (!= data "")

            (net-receive socket 'buf 1))

         (close socket))))



(define (P2P:P2P my-password peer-address my-address commands )

  (set 'peers (append peers (list peer-address)))

  (dolist (cmd commands)  (op-send peer-address my-address cmd ""))

  (set 'socket (net-listen  (get-port my-address)))

  (while true

    (while  (and (not (net-error)) (not (net-select socket "read" 1000)))

       (if (net-error) (print (net-error))))

    (set 'peer-socket (net-accept socket)) (net-receive peer-socket 'buf 1024 "/")

    (regex "^([a-zA-Z0-9]*) ([0-9:.]*) ([e-i])([^/]*)(/)" buf)

    (set 'peer-password $1)

    (set 'peer-address $2)

    (set 'peer-command $3)

    (set 'requested-filename $4)

    (set 'data $6)

    (if (= peer-password my-password)

        (case peer-command

          ("e" (begin

                   (set 'finished false)

                   (while (not finished)

                        (while (and (not (net-error)) (not (net-select peer-socket "read" 1000)))

                           (if (net-error) (print (net-error))))

                   (if (!= nil (net-receive peer-socket 'input-data 8192))

                      (begin

                        (append-file  requested-filename input-data)

                     (set 'finished true)))

               (net-send socket "x")))

          ("f"  (dolist (peer peers)   (op-send peer my-address requested-filename data)))

          ("g" (op-send peer-address my-address (append "e" requested-filename)

                   (read-file requested-filename)))

          ("h" (dolist (peer peers)  (op-send peer-address peer "i" "")))

          ("i" (append peers peer-address))))

    (close peer-socket)))



(context 'MAIN)





(P2P:P2P (main-args 2) (main-args 3) (main-args 4)  (slice (main-args) 5 -1))




I put some information in my blog http://sparebandwidth.blogspot.com">http://sparebandwidth.blogspot.com