Added a simple tcp server facility. See lab/greeting-server.ss.
This commit is contained in:
		
							parent
							
								
									9aaf306f16
								
							
						
					
					
						commit
						2119f44125
					
				|  | @ -0,0 +1,42 @@ | |||
| #!/usr/bin/env ikarus --r6rs-script  | ||||
| 
 | ||||
| (import (ikarus)) | ||||
| 
 | ||||
| (define (get-name p) | ||||
|   (list->string  | ||||
|     (let f () | ||||
|       (let ([x (read-char p)]) | ||||
|         (cond | ||||
|           [(or (eof-object? x) (char-whitespace? x)) | ||||
|            '()] | ||||
|           [else (cons x (f))]))))) | ||||
| 
 | ||||
| (define serve | ||||
|   (case-lambda | ||||
|     [(who port) | ||||
|      (let ([s (tcp-server-socket  | ||||
|                 (or (string->number port)  | ||||
|                     (error who "invalid port number" port)))]) | ||||
|        (call/cc | ||||
|          (lambda (k)  | ||||
|            (with-exception-handler k | ||||
|              (lambda ()  | ||||
|                (let f () | ||||
|                  (let-values ([(op ip) (accept-connection s)]) | ||||
|                    (let ([op (transcoded-port op (native-transcoder))] | ||||
|                          [ip (transcoded-port ip (native-transcoder))]) | ||||
|                      (display "What's your name? " op)  | ||||
|                      (let ([name (get-name ip)]) | ||||
|                        (printf "Connection from ~s\n" name) | ||||
|                        (fprintf op "Got it, ~a\n" name) | ||||
|                        (close-input-port ip) | ||||
|                        (close-output-port op)))) | ||||
|                  (f)))))) | ||||
|        (printf "\nClosing server ...\n") | ||||
|        (close-tcp-server-socket s))] | ||||
|     [(who) | ||||
|      (error who "missing port number")] | ||||
|     [(who . args) | ||||
|      (error who "too many arguments")])) | ||||
| 
 | ||||
| (apply serve (command-line)) | ||||
|  | @ -65,6 +65,7 @@ | |||
|      | ||||
|     tcp-connect tcp-connect-nonblocking | ||||
|     udp-connect udp-connect-nonblocking | ||||
|     tcp-server-socket accept-connection close-tcp-server-socket  | ||||
|     ) | ||||
| 
 | ||||
|    | ||||
|  | @ -119,6 +120,7 @@ | |||
|       process | ||||
|       tcp-connect tcp-connect-nonblocking | ||||
|       udp-connect udp-connect-nonblocking | ||||
|       tcp-server-socket accept-connection close-tcp-server-socket  | ||||
|       )) | ||||
| 
 | ||||
|   (module UNSAFE   | ||||
|  | @ -2187,7 +2189,41 @@ | |||
|               ls))))) | ||||
|     ) | ||||
| 
 | ||||
|    | ||||
|   (define-struct tcp-server (portnum fd)) | ||||
|    | ||||
|   (define (tcp-server-socket portnum)  | ||||
|     (unless (fixnum? portnum) | ||||
|       (error 'tcp-server-socket "not a fixnum" portnum)) | ||||
|     (let ([sock (foreign-call "ikrt_listen" portnum)]) | ||||
|       (cond | ||||
|         [(fx>= sock 0) (make-tcp-server portnum sock)] | ||||
|         [else (die 'tcp-server-socket "failed to start server")]))) | ||||
| 
 | ||||
|   (define (accept-connection s) | ||||
|     (define who 'accept-connection) | ||||
|     (unless (tcp-server? s)  | ||||
|       (die who "not a tcp server" s)) | ||||
|     (let ([fd (tcp-server-fd s)]) | ||||
|       (unless fd  | ||||
|         (die who "server is closed" s)) | ||||
|       (socket->ports  | ||||
|         (foreign-call "ikrt_accept" fd) | ||||
|         'accept-connection | ||||
|         #f | ||||
|         #t))) | ||||
| 
 | ||||
|   (define (close-tcp-server-socket s) | ||||
|     (define who 'close-tcp-server-socket) | ||||
|     (unless (tcp-server? s)  | ||||
|       (die who "not a tcp server" s)) | ||||
|     (let ([fd (tcp-server-fd s)]) | ||||
|       (unless fd  | ||||
|         (die who "server is closed" s)) | ||||
|       ;(file-close-proc who fd) | ||||
|       (let ([rv (foreign-call "ikrt_shutdown" fd)]) | ||||
|         (when (fx< rv 0) | ||||
|           (die who "failed to shutdown"))))) | ||||
| 
 | ||||
|   (set-fd-nonblocking 0 'init '*stdin*) | ||||
|   ) | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| 1421 | ||||
| 1422 | ||||
|  |  | |||
|  | @ -1397,6 +1397,9 @@ | |||
|     [udp-connect                      i] | ||||
|     [tcp-connect-nonblocking          i] | ||||
|     [udp-connect-nonblocking          i] | ||||
|     [tcp-server-socket                i] | ||||
|     [close-tcp-server-socket          i] | ||||
|     [accept-connection                i] | ||||
|     [&i/o-would-block                 i] | ||||
|     [make-i/o-would-block-condition   i] | ||||
|     [i/o-would-block-condition?       i] | ||||
|  |  | |||
|  | @ -214,6 +214,60 @@ ikrt_select(ikptr fds, ikptr rfds, ikptr wfds, ikptr xfds, ikpcb* pcb){ | |||
|   return fix(rv); | ||||
| } | ||||
| 
 | ||||
| ikptr | ||||
| ikrt_listen(ikptr port, ikpcb* pcb){ | ||||
|    | ||||
|   int sock = socket(AF_INET, SOCK_STREAM, 0); | ||||
|   if(sock < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   } | ||||
| 
 | ||||
|   struct sockaddr_in servaddr; | ||||
|   memset(&servaddr, 0, sizeof(struct sockaddr_in)); | ||||
|   servaddr.sin_family = AF_INET; | ||||
|   servaddr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|   servaddr.sin_port = htons(unfix(port)); | ||||
| 
 | ||||
|   int err; | ||||
| 
 | ||||
|   int reuse = 1; | ||||
|   err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)); | ||||
|   if(err < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   err = bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)); | ||||
|   if(err < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   } | ||||
| 
 | ||||
|   err = listen(sock, 1024); | ||||
|   if(err < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   } | ||||
|   return fix(sock); | ||||
| } | ||||
| 
 | ||||
| ikptr | ||||
| ikrt_accept(ikptr s, ikpcb* pcb){ | ||||
|   int sock = accept(unfix(s), NULL, NULL); | ||||
|   if(sock < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   }  | ||||
|   return fix(sock); | ||||
| } | ||||
| 
 | ||||
| ikptr | ||||
| ikrt_shutdown(ikptr s, ikpcb* pcb){ | ||||
|   int err = shutdown(unfix(s), SHUT_RDWR); | ||||
|   if(err < 0){ | ||||
|     return ikrt_io_error(); | ||||
|   }  | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ikptr | ||||
| ikrt_file_ctime(ikptr filename, ikptr res){ | ||||
|   struct stat s; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Abdulaziz Ghuloum
						Abdulaziz Ghuloum