diff options
author | Douglas-Richardson <Doug116654@gmail.com> | 2017-04-19 18:03:24 -0400 |
---|---|---|
committer | Douglas-Richardson <Doug116654@gmail.com> | 2017-04-19 18:03:24 -0400 |
commit | 5e3bdbeeb4cf32a8a937f3e2f018eae4f4dda286 (patch) | |
tree | fce846dfbfc7b7633e5aeb20a504891c224ececf /tests/tcpvanilla | |
parent | fe734a889397a9b0bbc55a997049d44166f18eae (diff) | |
parent | 95f7e7443363f21cda927b1446271d5008c439d6 (diff) |
Merge remote-tracking branch 'refs/remotes/origin/master' into grape
Diffstat (limited to 'tests/tcpvanilla')
-rw-r--r-- | tests/tcpvanilla/README.md | 20 | ||||
-rw-r--r-- | tests/tcpvanilla/client.rkt | 72 | ||||
-rw-r--r-- | tests/tcpvanilla/client2.rkt | 43 | ||||
-rw-r--r-- | tests/tcpvanilla/server.rkt | 58 | ||||
-rw-r--r-- | tests/tcpvanilla/tcpcommunication.rkt | 60 | ||||
-rw-r--r-- | tests/tcpvanilla/tcptalk.rkt | 30 |
6 files changed, 283 insertions, 0 deletions
diff --git a/tests/tcpvanilla/README.md b/tests/tcpvanilla/README.md new file mode 100644 index 0000000..b8e2883 --- /dev/null +++ b/tests/tcpvanilla/README.md @@ -0,0 +1,20 @@ +a simple experiment on communication via tcp ports + +a server runs continously servicing clients. Clients connect, send a message, and +server replies with a message. Message should appear in each separate REPL area +prompt + +run server.rkt in a REPL +``` +,en server.rkt +(define stop (serve 8080)) ;; starts serve listening at port 8080 +(stop) ;; to stop server and free the ports + +``` + +run client.rkt in a separate REPL +``` +,en client.rkt +(define stop (client 8080)) ;; starts client talking to server at port 8080 + +``` diff --git a/tests/tcpvanilla/client.rkt b/tests/tcpvanilla/client.rkt new file mode 100644 index 0000000..967d2b9 --- /dev/null +++ b/tests/tcpvanilla/client.rkt @@ -0,0 +1,72 @@ +#lang racket + +;; Both `server' and `accept-and-handle' change +;; to use a custodian. +;; To start server +;; (define stop (client 8080)) +;; use your web browser to connect localhost:8080 greeted with "hello world" +;; (stop) to close the server + +(define (client port-no) + (define main-client-cust (make-custodian)) + (parameterize ([current-custodian main-client-cust]) + ;; connect to server at port 8080 + (define-values (in out) (tcp-connect "localhost" port-no)) ;; define values + ;; binds to multiple values akin to unpacking tuples in python + ; (thread (lambda () + (chat in out) + (close-input-port in) + (close-output-port out)) + (custodian-shutdown-all main-client-cust)) + + ; (sleep 60) ;; run for 3 minutes then close + ; (define (loop) + ; (write (read-line (current-input-port)) out) + ; (flush-output out) + ; (write (read-line in) (current-output-port)) + ; (define listener (tcp-listen port-no 5 #t)) + ; (define (loop) + ; (accept-and-handle listener) + ; (loop)) + ; (thread loop))) + ; (custodian-shutdown-all main-client-cust) + #| (lambda () |# + ; (displayln "Goodbye, shutting down client\n") + #| (custodian-shutdown-all main-client-cust)) |# + +(define (chat in out) + ; (driver-loop in out) + (writeln "Ibrahim: Hello, anyone in chat?" out) + (flush-output out) ;; ports are buffered in racket must flush or you + ;; will read #eof + (sleep 10) ;; wait 10 seconds + (define serv-message (read-line in)) + (displayln serv-message) ;; read the servers replay message which is original + ;; with echo appended to it + ) + +; (define input-prompt "Hermes: ") + +(define (driver-loop in out) + ; (prompt-for-input input-prompt) + (display ">>> ") + (define input (read)) + (writeln (string-append "Ibrahim: " input) out) + (flush-output out) + ; (sleep 10) + (define output (read-line in)) + (displayln output) + (driver-loop in out)) + + +#| (let ((input (read))) |# +; ) +; (let ((input (read))) +; (let ((output (mc-eval input the-global-environment))) +; (announce-output output-prompt) +; (user-print output))) +; (driver-loop)) +; +; (define (announce-output string) +; (display string)) +#| |# diff --git a/tests/tcpvanilla/client2.rkt b/tests/tcpvanilla/client2.rkt new file mode 100644 index 0000000..47e3052 --- /dev/null +++ b/tests/tcpvanilla/client2.rkt @@ -0,0 +1,43 @@ +#lang racket + +;; Both `server' and `accept-and-handle' change +;; to use a custodian. +;; To start server +;; (define stop (client 8080)) +;; use your web browser to connect localhost:8080 greeted with "hello world" +;; (stop) to close the server + +(define (client port-no) + (define main-client-cust (make-custodian)) + (parameterize ([current-custodian main-client-cust]) + ;; connect to server at port 8080 + (define-values (in out) (tcp-connect "localhost" port-no)) ;; define values + ;; binds to multiple values akin to unpacking tuples in python + (thread (lambda () + (send-message in out) + (close-input-port in) + (close-output-port out)))) + (sleep 20) + ; (define (loop) + ; (write (read-line (current-input-port)) out) + ; (flush-output out) + ; (write (read-line in) (current-output-port)) + ; (define listener (tcp-listen port-no 5 #t)) + ; (define (loop) + ; (accept-and-handle listener) + ; (loop)) + ; (thread loop))) + (custodian-shutdown-all main-client-cust) + #| (lambda () |# + ; (displayln "Goodbye, shutting down client\n") + #| (custodian-shutdown-all main-client-cust)) |#) + +(define (send-message input-port output-port) + (writeln "Doug: Hello, how's it going?" output-port) + (flush-output output-port) ;; ports are buffered in racket must flush or you + ;; will read #eof + (sleep 10) ;; wait 10 seconds + (define serv-message (read-line input-port)) + (displayln serv-message) ;; read the servers replay message which is original + ;; with echo appended to it + ) diff --git a/tests/tcpvanilla/server.rkt b/tests/tcpvanilla/server.rkt new file mode 100644 index 0000000..bf72aff --- /dev/null +++ b/tests/tcpvanilla/server.rkt @@ -0,0 +1,58 @@ +#lang racket + +;; Both `server' and `accept-and-handle' change +;; to use a custodian. +;; To start server +;; (define stop (serve 8080)) +;; use your web browser to connect localhost:8080 greeted with "hello world" +;; (stop) to close the server + +(define (serve port-no) + (define main-cust (make-custodian)) + (parameterize ([current-custodian main-cust]) + (define listener (tcp-listen port-no 5 #t)) + (define (loop) + (accept-and-handle listener) + (loop)) + (thread loop)) + (lambda () + (displayln "\nGoodbye, shutting down all services\n") + (custodian-shutdown-all main-cust))) + +(define (accept-and-handle listener) + (define cust (make-custodian)) + (parameterize ([current-custodian cust]) + (define-values (in out) (tcp-accept listener)) + (thread (lambda () + (handle in out) ;; this handles connection with that specific client + (close-input-port in) + (close-output-port out)))) + ;; Watcher thread: + (thread (lambda () + (sleep 120) + (custodian-shutdown-all cust)))) + +(define (handle in out) + ; (server-loop in out) + (sleep 5) ;; wait 5 seconds to guarantee client has already send message + (define echo (read-line in)) ;; bind message to echo + (displayln (string-append echo "\n")) + ; echo back the message, appending echo + ; could regex match the input to extract the name + (writeln "Admin: Hello there" out) ;; append "echo " to echo and send back + (flush-output out) +) + +(define input-prompt "Hermes: ") + +(define (server-loop in out) + (define echo (read-line in)) + (displayln echo) + (display ">>> ") + + (define input (read)) + (writeln (string-append "Admin: " input) out) + (flush-output out) + ; (sleep 10) + (server-loop in out)) + diff --git a/tests/tcpvanilla/tcpcommunication.rkt b/tests/tcpvanilla/tcpcommunication.rkt new file mode 100644 index 0000000..134e697 --- /dev/null +++ b/tests/tcpvanilla/tcpcommunication.rkt @@ -0,0 +1,60 @@ +#lang racket +;; Reads input iteratively then sends it to local server +;; client reads back the message and displays it + +(require math/base) ;; for random number generation + +(define listener (tcp-listen 4326 5 #t)) +(define a (thread (lambda () + (define-values (s-in s-out) (tcp-accept listener)) + ; Discard the request header (up to blank line): + ;(regexp-match #rx"(\r\n|^)\r\n" s-in) + (sleep 10) + (define (echo) + (define input (read-line s-in)) + (displayln input s-out) + (flush-output s-out) + (if (eof-object? input) + (displayln "Done talking\n") + (echo))) + (echo) + (close-input-port s-in) + (close-output-port s-out) + (tcp-close listener) + 'ok))) + +(define t (thread (lambda () + (define-values (c-in c-out) (tcp-connect "localhost" 4326)) + (define input-prompt "input: ") + (define output-prompt "output: ") + + ;; prompt for username and bind to a variable username + (display "What's your name?\n") + (define username (read-line)) + (define usernamei (string-append username ": ")) ;; make username appear nicer in a prompt + (define fair (make-semaphore 1)) + + ;; intelligent read, quits when user types in "quit" + (define (read-loop-i) + ;(semaphore-wait fair) + ; (display usernamei) + (define input (read-line)) + ;; do something over here with input maybe send it out + + ;; Tests input if its a quit then kills all threads + ;; An if would be better here tbh + (cond ((string=? input "quit") (exit))) + (display (string-append output-prompt input "\n") c-out) + (flush-output c-out) + (displayln (read-line c-in)) ;; server echoes back sent input + ;(semaphore-post fair) + (read-loop-i) + ) + (read-loop-i) + 'ok))) + +;(kill-thread a) +;(kill-thread t) +(thread-wait t) +(display "DONE!!\n") + diff --git a/tests/tcpvanilla/tcptalk.rkt b/tests/tcpvanilla/tcptalk.rkt new file mode 100644 index 0000000..d069851 --- /dev/null +++ b/tests/tcpvanilla/tcptalk.rkt @@ -0,0 +1,30 @@ +#lang racket + +(define listener (tcp-listen 8083 5 #t)) ;; listener to service connection requests +;; client attempts to connect. Receives an input and output port +(define-values (client-in client-out) (tcp-connect "localhost" 8083)) +;; server accepts the connection request. Also gets a pair of ports +(define-values (server-in server-out) (tcp-accept listener)) + +;; client sends identifying message +(display (string-append "Client:My name is " "Ibrahim" "\n") + client-out) +(flush-output client-out) ;; must flush as ports are buffered in racket + +;; server receives and reads it +;; cooler if on separate racket instances +(read-line server-in) ;; --> "Client:My name is #hostname. +;; server replies +(display (string-append "Server:Hi " "Ibrahim" "\n") server-out) +(flush-output server-out) ;; flush flush + +;; client displays server message +(read-line client-in) +(close-output-port server-out) +(close-output-port client-out) +(read-line client-in) ;; --> eof object #eof +(read-line server-in) ;; --> eof object #eof +(tcp-close listener) +; (custodian-shutdown-all (current-custodian)) ;; release all resources including + ;; tcp, file, custom ports + ;; application exits |