;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; Write your own TCP client and server

;;

;; For more background on this stuff read up

;; on the Cocoa Classes NSInputStream/NSOutputStream

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;; server side

;;

;; collect all client connections in *server-connections*

(define *server-connections* '())


;; connection listener will be called for each new client connection

;; you are responsible for maintaining the list of client connections

;; the listener function accepts one integer argument specifying the 

;; socket that the client is connected on

;; You can call io:tcp:get-streams-from-socket to retrieve streams

;; that you can read from and write to.

(define connection-listener

   (lambda (socket)

      (print 'connection-on-socket socket)

      (let ((streams (io:tcp:get-streams-from-socket socket)))

         (set! *server-connections* (cons streams *server-connections*)))))



;; start server listening on port 9696 (or choose your own)

;; pass the process that you're running the server on 

;; and the name listener function to call back to

(io:tcp:start-server 9696 (ipc:get-process-name) "connection-listener")



;; start a server polling to check for incoming client data

;; this is where you do your thing!

(define server-data-polling

   (lambda ()

      (dotimes (i (length *server-connections*))

         (if (io:tcp:data-available? (list-ref *server-connections* i))

             (let ((new-data (io:tcp:read-from-stream (list-ref *server-connections* i) 256)))

                (print (objc:make "NSString" "initWithData:encoding:" new-data 4)))))

      (callback (+ (now) 5000) 'server-data-polling)))


(server-data-polling)



;;

;; client side

;;

;; establish a connection to a server 

(define streams-to-server (io:tcp:connect-to-server "localhost" 9696))


;; send some data to the server

(io:tcp:write-to-stream streams-to-server 

                        (objc:call (objc:string->nsstring "hello world") 

                                   "dataUsingEncoding:" 4))