python中的tcp套接字客户端如何与uwsgi对话?

问题描述 投票:0回答:2

Python中的tcp套接字客户端如何与uwsgi对话?

我的架构是

tcp 套接字客户端 -> nginx -> uwsgi

tcp 套接字客户端 -> uwsgi

python sockets nginx uwsgi python-sockets
2个回答
2
投票

通过与套接字对话

uwsgi
协议。该协议在 uWSGI 文档中进行了描述。

Python 文档包含 这里有一个关于 TCP 和 Unix 套接字的不错的教程

编辑: 有关工作示例,请参阅 https://github.com/akx/uwsgi-socket-example


0
投票

不清楚你到底想知道什么,所以让我从以下问题开始:

客户如何与

uwsgi
交谈?

$ python -m venv venv
$ venv/bin/pip install uwsgi-tools
$ venv/bin/uwsgi_curl /var/run/uwsgi-socket example.com

(这里,我在虚拟环境中安装

uwsgi-tools
软件包 (GitHub),并运行
uwsgi
客户端 (
uwsgi_curl
),将其传递给
uwsgi
服务器套接字 (
/var/run/uwsgi-socket
) 的路径)和 URL (
example.com
)。)

让我们看一下客户端和服务器端到底发送了什么内容。为此,让我们将

socat
放在它们之间:

$ socat -r /tmp/request -R /tmp/response \
    UNIX-LISTEN:/tmp/proxy UNIX-CONNECT:/var/run/uwsgi-socket

(此处

socat
/tmp/proxy
处的 Unix 域套接字与
uwsgi
/var/run/uwsgi-socket
处的套接字连接起来。请求存储在
/tmp/request
中,响应存储在
/tmp/response
中。)

并提出要求:

$ python -m venv /tmp/venv
$ /tmp/venv/bin/pip install uwsgi-tools
$ /tmp/venv/bin/uwsgi_curl /tmp/proxy example.com

$ xxd /tmp/request
00000000: 0094 0000 0f00 5345 5256 4552 5f50 524f  ......SERVER_PRO
00000010: 544f 434f 4c08 0048 5454 502f 312e 3109  TOCOL..HTTP/1.1.
00000020: 0050 4154 485f 494e 464f 0100 2f0e 0052  .PATH_INFO../..R
00000030: 4551 5545 5354 5f4d 4554 484f 4403 0047  EQUEST_METHOD..G
00000040: 4554 0b00 5245 5155 4553 545f 5552 4901  ET..REQUEST_URI.
00000050: 002f 0c00 5155 4552 595f 5354 5249 4e47  ./..QUERY_STRING
00000060: 0000 0900 4854 5450 5f48 4f53 540d 0065  ....HTTP_HOST..e
00000070: 7878 7861 6d70 6c65 2e63 6f6d 0b00 5345  xxxample.com..SE
00000080: 5256 4552 5f4e 414d 450d 0065 7878 7861  RVER_NAME..exxxa
00000090: 6d70 6c65 2e63 6f6d 0a                   mple.com.

$ xxd /tmp/response
00000000: 4854 5450 2f31 2e31 2032 3030 204f 4b0d  HTTP/1.1 200 OK.
00000010: 0a43 6f6e 7465 6e74 2d54 7970 653a 2074  .Content-Type: t
...

根据协议规范,首先是头部:

struct uwsgi_packet_header {
    uint8_t modifier1;
    uint16_t datasize;
    uint8_t modifier2;
};

在我们的例子中

modifier1 == 0
datasize == 0x94
(小端),
modifier2 == 0
。就这样:

标准 WSGI 请求后跟 HTTP 请求正文

然后是变量:

struct uwsgi_var {
    uint16_t key_size;
    uint8_t key[key_size];
    uint16_t val_size;
    uint8_t val[val_size];
}

A键:

00000000:           0f00 5345 5256 4552 5f50 524f      ..SERVER_PRO
00000010: 544f 434f 4c                             TOCOL

数值:

00000010:             08 0048 5454 502f 312e 31         ..HTTP/1.1

A键:

00000010:                                      09                 .
00000020: 0050 4154 485f 494e 464f                 .PATH_INFO

数值:

00000020:                          0100 2f                   ../

依此类推,直到最终变量:

00000070:                               0b00 5345              ..SE
00000080: 5256 4552 5f4e 414d 45                   RVER_NAME

00000080:                       0d 0065 7878 7861           ..exxxa
00000090: 6d70 6c65 2e63 6f6d                      mple.com

尾随的

0a
,我猜它是由
socat
添加来分隔请求的。那么请求长度(0x98 字节)等于标头长度(4 字节)+ var 长度(0x94 字节)。

现在,Python 中的 TCP 套接字客户端[编写?] 如何与

uwsgi
对话?首先删除
0a
中尾随的
/tmp/request
,例如与
vim
+
xxd
。然后:

$ socat TCP4-LISTEN:1234,reuseaddr \
    UNIX-CONNECT:/var/run/uwsgi-socket
$ cat /tmp/request | ncat example.com 1234 | less

(现在

socat
将 TCP 套接字 (
*:1234
) 连接到位于
/var/run/uwsgi-socket
的 Unix 域套接字。
ncat
让我们将由
uwsgi_curl
发送的请求发送到端口
1234
。)

另一方面,

uwsgi
也可以监听 TCP 套接字。所以另一个答案是,TCP 客户端无法直接连接到 Unix 域套接字服务器,只能通过诸如 socat
 之类的代理连接。

© www.soinside.com 2019 - 2024. All rights reserved.