official-guile-guide-examples.scm 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. (let* ([address-info (car (getaddrinfo "www.gnu.org" "http"))]
  2. [an-input-socket
  3. (socket (addrinfo:fam address-info) ; IPv4 or IPv6
  4. (addrinfo:socktype address-info) ; ???
  5. (addrinfo:protocol address-info) ; HTTP etc
  6. )])
  7. (setvbuf an-input-socket 'line)
  8. (connect an-input-socket (addrinfo:addr address-info))
  9. an-input-socket)
  10. (catch 'getaddrinfo-error
  11. (lambda ()
  12. (getaddrinfo "www.gnu.org" "gopher"))
  13. (lambda (key errcode)
  14. (cond ((= errcode EAI_SERVICE)
  15. (display "doesn't know about Gopher!\n"))
  16. ((= errcode EAI_NONAME)
  17. (display "www.gnu.org not found\\n"))
  18. (else
  19. (format #t "something wrong: ~a\n"
  20. (gai-strerror errcode))))))
  21. ;; =======================================
  22. ;; EXAMPLE USING INTERNET SOCKETS (SERVER)
  23. ;; =======================================
  24. (let ([s (socket PF_INET SOCK_STREAM 0)])
  25. ;; setsockopt socket level option-name value
  26. (setsockopt s SOL_SOCKET SO_REUSEADDR 1)
  27. ;; Specific address?
  28. ;; bind the socket to:
  29. ;; a port (2904),
  30. ;; a protocol family (AF_INET),
  31. ;; and an incoming addresses (INADDR_ANY) – (all available interfaces?)
  32. ;; (bind s AF_INET (inet-pton AF_INET "127.0.0.1") 2904)
  33. (bind s AF_INET INADDR_ANY 12345)
  34. ;; enable the port to listen
  35. ;; maximum queue of incoming connections is 5
  36. (listen s 5)
  37. (simple-format #t "Listening for clients in pid: ~S" (getpid))
  38. (newline)
  39. ;; loop for getting messages
  40. (while #t
  41. (let* ((client-connection (accept s))
  42. (client-details (cdr client-connection))
  43. (client (car client-connection)))
  44. (simple-format #t
  45. "Got new client connection: ~S"
  46. client-details)
  47. (newline)
  48. (simple-format #t
  49. "Client address: ~S"
  50. (gethostbyaddr (sockaddr:addr client-details)))
  51. (newline)
  52. ;; Send back the greeting to the client port
  53. (display "Hello client\r\n" client)
  54. (close client))))
  55. ;; =====================================
  56. ;; LISTENING ON A PORT – MAKING A SERVER
  57. ;; =====================================
  58. ;; 1. MAKE A SOCKET
  59. ;; 2. BIND PORT TO AN ADDRESS
  60. ;; Scheme Procedure: bind sock sockaddr
  61. ;; Scheme Procedure: bind sock AF_INET ipv4addr port
  62. ;; Scheme Procedure: bind sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
  63. ;; Scheme Procedure: bind sock AF_UNIX path
  64. (bind sock ; the socket with which we will work to get stuff we listen for
  65. AF_INET ; IPv4
  66. INADDR_ANY ; allow inbound from everywhere
  67. 12345)) ; listen on port 12345
  68. ;; ALTERNATiVELY
  69. (bind sock
  70. (make-socket-address AF_INET
  71. INADDR_ANY
  72. 12345))
  73. ;; 3. ENABLE SOCKET TO ACCEPT CONNECTION REQUESTS
  74. (let ([backlog-of-connection-requests 10])
  75. (listen sock backlog-of-connection-requests))
  76. ;; 4. ACCEPT A CONNECTION
  77. ;; "flags, if given, may include sock_cloexec or sock_nonblock,
  78. ;; which like o_cloexec and o_nonblock apply to the newly accepted socket. "
  79. ;; (accept sock [flags])
  80. ;; A socket cannot by used for communication until it has been connected somewhere,
  81. ;; usually with either connect (client) or accept (server).
  82. (accept sock)
  83. ;; ===================================
  84. ;; CONNECT TO A PORT – MAKING A CLIENT
  85. ;; ===================================
  86. ;; 1. MAKE A SOCKET
  87. ;; PF = protocol family?
  88. (socket PF_INET 0 (protoent:proto (getprotobyname "TCP")))
  89. ;; 2. CONNECT TO ADDRESS
  90. ;; Scheme Procedure: connect sock sockaddr
  91. ;; Scheme Procedure: connect sock AF_INET ipv4addr port
  92. ;; Scheme Procedure: connect sock AF_INET6 ipv6addr port [flowinfo [scopeid]]
  93. ;; Scheme Procedure: connect sock AF_UNIX path
  94. (connect sock AF_INET INADDR_LOOPBACK 23)
  95. (connect sock (make-socket-address AF_INET INADDR_LOOPBACK 23))
  96. ;; ======================
  97. ;; SHUTDOWN COMMUNICATION
  98. ;; ======================
  99. ;; values for `how`:
  100. ;; 0: Stop receiving data for this socket. If further data arrives, reject it.
  101. ;; 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.
  102. ;; 2 Stop both reception and transmission.
  103. (shutdown sock 0)
  104. (shutdown sock 1)
  105. (shutdown sock 2)