123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- (let* ([address-info (car (getaddrinfo "www.gnu.org" "http"))]
- [an-input-socket
- (socket (addrinfo:fam address-info) ; IPv4 or IPv6
- (addrinfo:socktype address-info) ; ???
- (addrinfo:protocol address-info) ; HTTP etc
- )])
- (setvbuf an-input-socket 'line)
- (connect an-input-socket (addrinfo:addr address-info))
- an-input-socket)
- (catch 'getaddrinfo-error
- (lambda ()
- (getaddrinfo "www.gnu.org" "gopher"))
- (lambda (key errcode)
- (cond ((= errcode EAI_SERVICE)
- (display "doesn't know about Gopher!\n"))
- ((= errcode EAI_NONAME)
- (display "www.gnu.org not found\\n"))
- (else
- (format #t "something wrong: ~a\n"
- (gai-strerror errcode))))))
- ;; =======================================
- ;; EXAMPLE USING INTERNET SOCKETS (SERVER)
- ;; =======================================
- (let ([s (socket PF_INET SOCK_STREAM 0)])
- ;; setsockopt socket level option-name value
- (setsockopt s SOL_SOCKET SO_REUSEADDR 1)
- ;; Specific address?
- ;; bind the socket to:
- ;; a port (2904),
- ;; a protocol family (AF_INET),
- ;; and an incoming addresses (INADDR_ANY) – (all available interfaces?)
- ;; (bind s AF_INET (inet-pton AF_INET "127.0.0.1") 2904)
- (bind s AF_INET INADDR_ANY 12345)
- ;; enable the port to listen
- ;; maximum queue of incoming connections is 5
- (listen s 5)
- (simple-format #t "Listening for clients in pid: ~S" (getpid))
- (newline)
- ;; loop for getting messages
- (while #t
- (let* ((client-connection (accept s))
- (client-details (cdr client-connection))
- (client (car client-connection)))
- (simple-format #t
- "Got new client connection: ~S"
- client-details)
- (newline)
- (simple-format #t
- "Client address: ~S"
- (gethostbyaddr (sockaddr:addr client-details)))
- (newline)
- ;; Send back the greeting to the client port
- (display "Hello client\r\n" client)
- (close client))))
- ;; =====================================
- ;; LISTENING ON A PORT – MAKING A SERVER
- ;; =====================================
- ;; 1. MAKE A SOCKET
- ;; 2. BIND PORT TO AN ADDRESS
- ;; Scheme Procedure: bind sock sockaddr
- ;; Scheme Procedure: bind sock AF_INET ipv4addr port
- ;; Scheme Procedure: bind sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
- ;; Scheme Procedure: bind sock AF_UNIX path
- (bind sock ; the socket with which we will work to get stuff we listen for
- AF_INET ; IPv4
- INADDR_ANY ; allow inbound from everywhere
- 12345)) ; listen on port 12345
- ;; ALTERNATiVELY
- (bind sock
- (make-socket-address AF_INET
- INADDR_ANY
- 12345))
- ;; 3. ENABLE SOCKET TO ACCEPT CONNECTION REQUESTS
- (let ([backlog-of-connection-requests 10])
- (listen sock backlog-of-connection-requests))
- ;; 4. ACCEPT A CONNECTION
- ;; "flags, if given, may include sock_cloexec or sock_nonblock,
- ;; which like o_cloexec and o_nonblock apply to the newly accepted socket. "
- ;; (accept sock [flags])
- ;; A socket cannot by used for communication until it has been connected somewhere,
- ;; usually with either connect (client) or accept (server).
- (accept sock)
- ;; ===================================
- ;; CONNECT TO A PORT – MAKING A CLIENT
- ;; ===================================
- ;; 1. MAKE A SOCKET
- ;; PF = protocol family?
- (socket PF_INET 0 (protoent:proto (getprotobyname "TCP")))
- ;; 2. CONNECT TO ADDRESS
- ;; Scheme Procedure: connect sock sockaddr
- ;; Scheme Procedure: connect sock AF_INET ipv4addr port
- ;; Scheme Procedure: connect sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
- ;; Scheme Procedure: connect sock AF_UNIX path
- (connect sock AF_INET INADDR_LOOPBACK 23)
- (connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))
- ;; ======================
- ;; SHUTDOWN COMMUNICATION
- ;; ======================
- ;; values for `how`:
- ;; 0: Stop receiving data for this socket. If further data arrives, reject it.
- ;; 1: Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don’t retransmit it if it is lost.
- ;; 2 Stop both reception and transmission.
- (shutdown sock 0)
- (shutdown sock 1)
- (shutdown sock 2)
|