用sbcl和uscoket库编写的简单服务器不适用于AWS实例

彼得罗迪托

标题是明确的。

可重复的步骤

*使用端口80上的HTTP规则在AWS上启动Ubuntu实例

*安装sbcl

sudo apt install sbcl -y

*为根安装usocket库

请参阅下一步,以了解我为什么以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")

*使用Lisp之地示例(http://landoflisp.com/

在一个名为 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

*补充诊断:

AWS安全组/ inboud规则

╔══════╦══════════╦════════════╦═══════════╗
║ 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 ║
╚══════╩══════════╩════════════╩═══════════╝

iptables

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

不出所料!

从远处的机器ping

需要向入站安全组策略添加自定义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

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

psycopg2不适用于AWS Lambda上的无服务器框架部署

来自分类Dev

SetState不适用于服务器中的数据

来自分类Dev

jQuery似乎不适用于服务器控制

来自分类Dev

OBS不适用于Wayland显示服务器

来自分类Dev

CronJob和其他逻辑不适用于VPS / Cpanel服务器

来自分类Dev

SVN:分支和重新集成不适用于更新的服务器

来自分类Dev

GET和POST请求不适用于ip地址(内部服务器错误)

来自分类Dev

适用于简单服务的AWS数据库

来自分类Dev

表格不适用于服务器,仅适用于移动版本

来自分类Dev

Laravel路由适用于内部Web服务器,但不适用于WAMP

来自分类Dev

Symfony 项目适用于实时服务器,但不适用于 wamp

来自分类Dev

散景服务器不适用于条形图,但适用于绘图

来自分类Dev

php 如果查询适用于 wamp 但不适用于实时服务器

来自分类Dev

无服务器示例不适用于无服务器本地堆栈插件

来自分类Dev

粘性会话不适用于多个apache虚拟主机和多个JBoss 7.2服务器组

来自分类Dev

反应校验和无效:客户端屏幕高度属性不适用于服务器端

来自分类Dev

加载〜400(错误请求)。XmlHttpRequest适用于本地,但不适用于服务器端

来自分类Dev

User.find_by([“ name LIKE?”不适用于heroku,但适用于开发服务器

来自分类Dev

Magento:自定义模块适用于本地主机但不适用于服务器

来自分类Dev

Powershell 脚本适用于服务器,但不适用于 cloudformation cfn-init 函数

来自分类Dev

来自 boost 的 udp 服务器不适用于多线程,但仅适用于主线程

来自分类Dev

Terraform销毁不适用于AWS中的数据库实例

来自分类Dev

如何获得适用于我的AWS服务器的有用的负载测试数据?

来自分类Dev

如何获得适用于我的AWS服务器的有用的负载测试数据?

来自分类Dev

带有Backbone.js路由器的HTML5 pushState不适用于特定服务器,但适用于其他服务器

来自分类Dev

会话变量适用于本地服务器,但不适用于使用 symfony2.8 的托管服务器

来自分类Dev

php 套接字服务器仅适用于本地主机但不适用于实时服务器

来自分类Dev

docker中的端口映射不适用于python服务器

来自分类Dev

Intl PHP扩展不适用于xampp服务器

Related 相关文章

  1. 1

    psycopg2不适用于AWS Lambda上的无服务器框架部署

  2. 2

    SetState不适用于服务器中的数据

  3. 3

    jQuery似乎不适用于服务器控制

  4. 4

    OBS不适用于Wayland显示服务器

  5. 5

    CronJob和其他逻辑不适用于VPS / Cpanel服务器

  6. 6

    SVN:分支和重新集成不适用于更新的服务器

  7. 7

    GET和POST请求不适用于ip地址(内部服务器错误)

  8. 8

    适用于简单服务的AWS数据库

  9. 9

    表格不适用于服务器,仅适用于移动版本

  10. 10

    Laravel路由适用于内部Web服务器,但不适用于WAMP

  11. 11

    Symfony 项目适用于实时服务器,但不适用于 wamp

  12. 12

    散景服务器不适用于条形图,但适用于绘图

  13. 13

    php 如果查询适用于 wamp 但不适用于实时服务器

  14. 14

    无服务器示例不适用于无服务器本地堆栈插件

  15. 15

    粘性会话不适用于多个apache虚拟主机和多个JBoss 7.2服务器组

  16. 16

    反应校验和无效:客户端屏幕高度属性不适用于服务器端

  17. 17

    加载〜400(错误请求)。XmlHttpRequest适用于本地,但不适用于服务器端

  18. 18

    User.find_by([“ name LIKE?”不适用于heroku,但适用于开发服务器

  19. 19

    Magento:自定义模块适用于本地主机但不适用于服务器

  20. 20

    Powershell 脚本适用于服务器,但不适用于 cloudformation cfn-init 函数

  21. 21

    来自 boost 的 udp 服务器不适用于多线程,但仅适用于主线程

  22. 22

    Terraform销毁不适用于AWS中的数据库实例

  23. 23

    如何获得适用于我的AWS服务器的有用的负载测试数据?

  24. 24

    如何获得适用于我的AWS服务器的有用的负载测试数据?

  25. 25

    带有Backbone.js路由器的HTML5 pushState不适用于特定服务器,但适用于其他服务器

  26. 26

    会话变量适用于本地服务器,但不适用于使用 symfony2.8 的托管服务器

  27. 27

    php 套接字服务器仅适用于本地主机但不适用于实时服务器

  28. 28

    docker中的端口映射不适用于python服务器

  29. 29

    Intl PHP扩展不适用于xampp服务器

热门标签

归档