标题是明确的。
sudo apt install sbcl -y
请参阅下一步,以了解我为什么以root用户身份执行此操作
curl -O https://beta.quicklisp.org/quicklisp.lisp
sudo sbcl --load quicklisp.lisp
接下来的几行需要输入到sbcl REPL中
(quicklisp-quickstart:install)
(ql:add-to-init-file)
(ql:quickload "usocket")
在一个名为 server.lisp
(require 'usocket)
(defun http-char (c1 c2 &optional (default #\Space))
(let ((code (parse-integer
(coerce (list c1 c2) 'string)
:radix 16
:junk-allowed t)))
(if code
(code-char code)
default)))
(defun decode-param (s)
(labels ((f (lst)
(when lst
(case (car lst)
(#\% (cons (http-char (cadr lst) (caddr lst))
(f (cdddr lst))))
(#\+ (cons #\space (f (cdr lst))))
(otherwise (cons (car lst) (f (cdr lst))))))))
(coerce (f (coerce s 'list)) 'string)))
(defun parse-params (s)
(let* ((i1 (position #\= s))
(i2 (position #\& s)))
(cond (i1 (cons (cons (intern (string-upcase (subseq s 0 i1)))
(decode-param (subseq s (1+ i1) i2)))
(and i2 (parse-params (subseq s (1+ i2))))))
((equal s "") nil)
(t s))))
(defun parse-url (s)
(let* ((url (subseq s
(+ 2 (position #\space s))
(position #\space s :from-end t)))
(x (position #\? url)))
(if x
(cons (subseq url 0 x) (parse-params (subseq url (1+ x))))
(cons url '()))))
(defun get-header (stream)
(let* ((s (read-line stream))
(h (let ((i (position #\: s)))
(when i
(cons (intern (string-upcase (subseq s 0 i)))
(subseq s (+ i 2)))))))
(when h
(cons h (get-header stream)))))
(defun get-content-params (stream header)
(let ((length (cdr (assoc 'content-length header))))
(when length
(let ((content (make-string (parse-integer length))))
(read-sequence content stream)
(parse-params content)))))
(defun serve (request-handler)
(let ((socket (usocket:socket-listen #(127 0 0 1) 80)))
(unwind-protect
(loop (with-open-stream (stream (usocket:socket-stream
(usocket:socket-accept socket)))
(let* ((url (parse-url (read-line stream)))
(path (car url))
(header (get-header stream))
(params (append (cdr url)
(get-content-params stream header)))
(*standard-output* stream))
(funcall request-handler path header params))))
(usocket:socket-close socket))))
(defun hello-request-handler (path header params)
(if (equal path "greeting")
(let ((name (assoc 'name params)))
(if (not name)
(princ "<html><form>What is your name?<input name='name'/></form></html>")
(format t "<html>Nice to meet you, ~a!</html>" (cdr name))))
(princ "Sorry... I don't know that page")))
(serve #'hello-request-handler)
然后,您以root身份启动服务器:
sudo sbcl --load "server.lisp"
我正在使用root用户,因为我无法摆脱普通用户的以下错误消息
The condition Socket error in "bind": 13 (Permission denied) occurred with errno :0.
然后一切似乎都正确,但是我无法使用以下方法从标准浏览器访问服务器:
http://IPv4.Public.IP:80
╔══════╦══════════╦════════════╦═══════════╗
║ Type ║ Protocol ║ Port Range ║ Source ║
╠══════╬══════════╬════════════╬═══════════╣
║ HTTP ║ TCP ║ 80 ║ 0.0.0.0/0 ║
║ HTTP ║ TCP ║ 80 ║ ::/0 ║
║ SSH ║ TCP ║ 22 ║ 0.0.0.0/0 ║
╚══════╩══════════╩════════════╩═══════════╝
sudo iptables -L -v
Chain INPUT (policy ACCEPT 346 packets, 23760 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 244 packets, 32428 bytes)
pkts bytes target prot opt in out source destination
sudo iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
curl 127.0.0.1
Sorry... I don't know that page
不出所料!
需要向入站安全组策略添加自定义ICMP规则(现在我知道这ping
是使用ICMP ...)
ping 35.180.138.87
64 bytes from 35.180.138.87: icmp_seq=1 ttl=49 time=173 ms
64 bytes from 35.180.138.87: icmp_seq=2 ttl=49 time=32.2 ms
^C
--- 35.180.138.87 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1005ms
rtt min/avg/max/mdev = 32.248/102.884/173.520/70.636 ms
curl 35.180.138.87
curl: (7) Failed to connect to 35.180.138.87 port 80: Connection refused
netstat -nlp
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN -
仅当我的服务器正在运行时,才会出现带有端口80的行。
问题出在用于打开套接字的IP地址中,即 127.0.0.1
我尝试使用AWS提供的IPv4地址,但这不是解决方案
相反,必须从主机服务器中搜索IP地址:
sudo ip addr
答案是例如 111.111.111.111
然后在Lisp代码中使用找到的地址
(let ((socket (usocket:socket-listen #(111 111 111 111) 80)))
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句