iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >wsgi 协议
  • 244
分享到

wsgi 协议

协议wsgi 2023-01-30 23:01:37 244人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

前言 本来没打算这么早就学习 wsgi 的,因为想要学习python 是如何处理网络请求的绕不开 wsgi,所以只好先学习一下 wsgi。先对 wsgi 有个印象,到了学习 Django 运行方式以及如何处理网络请求数据的时候就会感觉很

前言

本来没打算这么早就学习 wsgi 的,因为想要学习python 是如何处理网络请求的绕不开 wsgi,所以只好先学习一下 wsgi。先对 wsgi 有个印象,到了学习 Django 运行方式以及如何处理网络请求数据的时候就会感觉很顺畅了。本文参考

什么是 WSGI

wsgi 的全称是WEB Server Gateway Interface,这是一个规范,描述了 web server 如何与 web application 交互、web application 如何处理请求。该规范的具体描述在 PEP3333。WSGI 既要实现 web server,也要实现 web application。在 DjanGo 中的 app 其实就是 web application,而 web server其实在使用命令行输入Python manage.py runserver或者使用 PyCharm 开启 Django 项目的时候就把runserver当做参数传给了 manage.py里面

经过判断然后执行execute_from_command_line(sys.argv),sys.argv就是 runserver命令,进入该函数,发现执行了utility.execute()函数,进入函数查看源码

def execute(self):
    """
    Given the command-line arguments, this figures out which subcommand is
    being run, creates a parser appropriate to that command, and runs it.
    """
    try:
        subcommand = self.argv[1]
    except IndexError:
        subcommand = 'help'  # Display help if no arguments were given.

    # Preprocess options to extract --settings and --pythonpath.
    # These options could affect the commands that are available, so they
    # must be processed early.
    parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False)
    parser.add_argument('--settings')
    parser.add_argument('--pythonpath')
    parser.add_argument('args', nargs='*')  # catch-all
    try:
        options, args = parser.parse_known_args(self.argv[2:])
        handle_default_options(options)
    except CommandError:
        pass  # Ignore any option errors at this point.

    try:
        settings.INSTALLED_APPS
    except ImproperlyConfigured as exc:
        self.settings_exception = exc

    if settings.configured:
        # Start the auto-reloading dev server even if the code is broken.
        # The hardcoded condition is a code smell but we can't rely on a
        # flag on the command class because we haven't located it yet.
        if subcommand == 'runserver' and '--noreload' not in self.argv:
            try:
                autoreload.check_errors(django.setup)()
            except Exception:
                # The exception will be raised later in the child process
                # started by the autoreloader. Pretend it didn't happen by
                # loading an empty list of applications.
                apps.all_models = defaultdict(OrderedDict)
                apps.app_configs = OrderedDict()
                apps.apps_ready = apps.models_ready = apps.ready = True

                # Remove options not compatible with the built-in runserver
                # (e.g. options for the contrib.staticfiles' runserver).
                # Changes here require manually testing as described in
                # #27522.
                _parser = self.fetch_command('runserver').create_parser('django', 'runserver')
                _options, _args = _parser.parse_known_args(self.argv[2:])
                for _arg in _args:
                    self.argv.remove(_arg)

        # In all other cases, django.setup() is required to succeed.
        else:
            django.setup()

    self.autocomplete()

    if subcommand == 'help':
        if '--commands' in args:
            sys.stdout.write(self.main_help_text(commands_only=True) + '\n')
        elif len(options.args) < 1:
            sys.stdout.write(self.main_help_text() + '\n')
        else:
            self.fetch_command(options.args[0]).print_help(self.prog_name, options.args[0])
    # Special-cases: We want 'django-admin --version' and
    # 'django-admin --help' to work, for backwards compatibility.
    elif subcommand == 'version' or self.argv[1:] == ['--version']:
        sys.stdout.write(django.get_version() + '\n')
    elif self.argv[1:] in (['--help'], ['-h']):
        sys.stdout.write(self.main_help_text() + '\n')
    else:
        self.fetch_command(subcommand).run_from_argv(self.argv)

源码太长了。。。我把关键地方抠出来:

if settings.configured:
    # Start the auto-reloading dev server even if the code is broken.
    # The hardcoded condition is a code smell but we can't rely on a
    # flag on the command class because we haven't located it yet.
    if subcommand == 'runserver' and '--noreload' not in self.argv:
        try:
            autoreload.check_errors(django.setup)()
        except Exception:
            # The exception will be raised later in the child process
            # started by the autoreloader. Pretend it didn't happen by
            # loading an empty list of applications.
            apps.all_models = defaultdict(OrderedDict)
            apps.app_configs = OrderedDict()
            apps.apps_ready = apps.models_ready = apps.ready = True

            # Remove options not compatible with the built-in runserver
            # (e.g. options for the contrib.staticfiles' runserver).
            # Changes here require manually testing as described in
            # #27522.
            _parser = self.fetch_command('runserver').create_parser('django', 'runserver')
            _options, _args = _parser.parse_known_args(self.argv[2:])
            for _arg in _args:
                self.argv.remove(_arg)

    # In all other cases, django.setup() is required to succeed.
    else:
        django.setup()

这里也是注释最多的地方,可以看到有runserver这条命令,然后这里面在经过一系列的判断最后要执行最后一行代码:

self.fetch_command(subcommand).run_from_argv(self.argv)

这行代码等学习 Django 处理流程的时候在详细解释,反正只要知道目前经过这个函数的执行,Django 的 web server 成功运行了。

实现了 WSGI 的模块/库有 wsgiref(python 内置,下面也是用这个来举例)、werkzeug.serving、twisted.web等。

当前运行在 wsgi 之上的 web 框架有 Bottle、flask、Django 等。WSGI server 所做的工作仅仅是将客户端收到的请求传递给 WSGI application,然后将 WSGI application 的返回值作为相应传给客户端。WSGI application 可以是栈式的,这个栈的中间部分叫做中间件,两端是必须要实现的 application 和 server。所以对客户端来说,中间件扮演服务器;对服务器来说,中间件扮演客户端。在 Django 中wsgi 收到的数据用 request对象表示,要传给客户端的数据用 Httpresponse对象表示。

搭建一个 wsgi 服务

在上章节说了 python 有个内置的 WSGI 库叫 wsgiref。

首先看下项目结构:

# templates为模板(html)文件夹
# start.py 为项目入口,
# urls.py 为路由配置
# views.py 为具体处理路由逻辑代码

start 文件

# start.py文件
from wsgiref.simple_server import make_server
from urls import urls

def app(env, response):
    # 在这里,
    print(env)
    route = env['PATH_INFO']
    print(response)
    
    # 设置状态码与响应头
    response('200 OK', [('Content-type', 'text/html')])
    
    # 设置错误处理
    data = urls['/error']()
    
    # 设置路由处理
    if route in urls:
        data = urls[route]()
        
    # 返回二进制响应体
    return [data]

if __name__ == '__main__':
    
    # 创建服务器对象
    server = make_server('', 8808, app)
    print('服务:http://localhost:8808')
    
    # 服务保持运行状态
    server.serve_forever()
    
    # WSGI server 是一个 web server,其处理一个 HTTP 请求的逻辑如下:
    # iterable = app(env, response)
    #     for date in iterable:
    #         send data to client

其实这个模块底层使用了 sockserver 模块,我前面的博客也有介绍。经过 make_server就成功开启了wsgi server,然后server_forever()是为了将服务器持续接收客户端请求,采用的是轮询方法,该方法里面的参数 poll_interval=0.5,采用的是0.5秒轮询一次,轮询采用的是 selector学名叫多路复用技术。

urls 文件

# urls.py文件
from views import *
urls = {
    '/index': index, # 函数地址
    '/error': error
}

该文件就是处理路由的,然后将对应的路由映射到相应的逻辑处理函数。

views 文件

# 处理请求的功能函数(处理结果返回的都是页面 => 功能函数)
# 利用 jinja2来渲染模板,将后台数据传给前台

from jinjia2 import Template

# 处理主页请求
def index():
    with open('templates/index.html', 'r') as f:
        dt = f.read()
    tem = Template(dt)
    
    # 将后台数据通过模板渲染功能渲染传给前台页面
    resp = tem.render(name='主页')
    return resp.encode('utf-8')

# 处理图标请求
def ico():
    with open('favicon.ico', 'rb') as f:
        dt = f.read()
    return dt

# 处理错误请求
def error():
    return b'404'

templates

该文件夹里面放的伪要返回给前端相关资源,比如index.html

测试

  • index 测试

  • error 测试

WSGI application接口

在上面wsgi 服务中的 app 就是 wsgi 中的 application,该接口应该实现为一个可调用对象,例如函数、方法、类、含__call__方法的实例。这个可调用对象可以接收两个参数:

  • 一个字典,该字典可以包含了客户端请求的信息以及其他信息,可以认为是请求上下文,一般叫做 environment(在这里我取名为 env);
  • 一个用于发送 HTTP 状态码与响应头的回调函数。(具体怎么回调的还不清楚)

同时,可调用对象的返回值是响应体(response body),响应正文是可迭代的、并包含了多个字符串。(加了中括号可以减少迭代次数,提高效率)

把上面的 app 代码拷下来:

def app(env, response):
    # 在这里,
    print(env)
    route = env['PATH_INFO']
    print(response)
    
    # 设置状态码与响应头
    response('200 OK', [('Content-type', 'text/html')])
    
    # 设置错误处理
    data = urls['/error']()
    
    # 设置路由处理
    if route in urls:
        data = urls[route]()
        
    # 返回二进制响应体
    return [data]

当我对服务端发起请求时,会打印出 env,如下:

{'PATH': '/Users/jingxing/Virtualenv/py3-env1/bin:/Users/jingxing/.nvm/versions/node/v4.9.1/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/python_study/mongoDB/bin://Volumes/python_study/mongodb/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/python_study/Applications/mongodb-osx-x86_64-3.6.3/bin::/usr/local/Mysql/bin', 'PS1': '(py3-env1) ', 'VERSIONER_PYTHON_VERSION': '2.7', 'LS_OPTIONS': '--color=auto', 'LOGNAME': 'jingxing', 'XPC_SERVICE_NAME': 'com.jetbrains.pycharm.23248', 'PWD': '/Users/jingxing/django_project/day01', 'PYCHARM_HOSTED': '1', 'NODE_PATH': '/Users/jingxing/.nvm/versions/node/v4.9.1/lib/node_modules', 'PYCHARM_MATPLOTLIB_PORT': '62845', 'PYTHONPATH': '/Users/jingxing/django_project/day01:/Users/jingxing/django_project/day04:/Users/jingxing/django_project/day02:/Users/jingxing/PycharmProjects/youku/youkusecond:/Users/jingxing/django_project/day03:/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend', 'NVM_CD_FLAGS': '', 'NVM_DIR': '/Users/jingxing/.nvm', 'shell': '/bin/bash', 'LSCOLORS': 'CxfxcxdxbxegedabagGxGx', 'PYTHONIOENcoding': 'UTF-8', 'VERSIONER_PYTHON_PREFER_32_BIT': 'no', 'USER': 'jingxing', 'CLICOLOR': 'Yes', 'TMPDIR': '/var/folders/yl/3Drd7wf93f90sfkgpc2zg9cr0000gn/T/', 'ssh_AUTH_SOCK': '/private/tmp/com.apple.launchd.ujA3r16JUC/Listeners', 'VIRTUAL_ENV': '/Users/jingxing/Virtualenv/py3-env1', 'XPC_FLAGS': '0x0', 'PYTHONUNBUFFERED': '1', '__CF_USER_TEXT_ENCODING': '0x1F5:0x0:0x0', 'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.gOrXw3Il2u/Render', 'LC_CTYPE': 'en_US.UTF-8', 'NVM_BIN': '/Users/jingxing/.nvm/versions/node/v4.9.1/bin', 'HOME': '/Users/jingxing', 'SERVER_NAME': 'jingxingdeMacBook-Pro.local', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8808', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8808', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7', 'HTTP_COOKIE': 'csrftoken=YjPgsyb6TW4fen2fxjy6DHzZYFlBU4SsAuE9AVqWRjLIhymeAlukqjVBpL7KTPPH', 'wsgi.input': <_io.BufferedReader name=7>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>}

这些参数值得关注的为:

  • PATH_INFO:路由信息;
  • SERVER_PORT:端口;
  • HTTP_HOST:ip;
  • SERVER_PROTOCOL:服务器端通信协议

可迭代响应

在 app 中向客户端返回数据时,写的为

return [data],如果改为return date,这将会导致 WSGI 程序的响应变慢。原因是字符串date也是可迭代的,它的每一次迭代只能得到 1bytes 的数据量,这也意味着每一次只向客户端发送1bytes 的数据,直到发送完毕为止。所以推荐使用return [data]。这里的数据是怎么返回的目前还不清楚,保留疑问。。。

如果可迭代响应含有多个字符串,那么Content-Length应该是这些字符串长度之和。

解析 GET 请求

运行 start.py文件,在浏览器中访问http://localhost:8808/?id=1&name=musibii,可以在响应内容中找到到:

'QUERY_STRING': 'id=1&name=musibii'
'REQUEST_METHOD': 'GET'

cgi.parse_qs()函数可以很方便的处理 QUERY_STRING,同时需要cgi.escape()处理特殊字符以防止脚本注入,如下:

from cgi import parse_qs, escape

QUERY_STRING = 'id=1&name=musibii'
d = parse_qs(QUERY_STRING)
print(d.get('id', [''])[0]) # ['']是默认值,如果在QUERY_STRING中没找到则返回默认值
print(d.get('name',[]))

print(escape('<script>alert(123);</script>'))

运行结果:

1
['musibii']
&lt;script&gt;alert(123);&lt;/script&gt;

处理 GET 请求的动态网页

from wsgiref.simple_server import make_server
from cgi import parse_qs, escape

# html中 fORM 的 method 默认为 get,action 是当前页面
html = '''
<html>
<body>
   <form method="get" action="">
        <p>
           Age: <input type="text" name="age" value="%(age)s">
        </p>
        <p>
            Hobbies:
            <input
                name="hobbies" type="checkbox" value="software"
                %(checked-software)s
            > Software
            <input
                name="hobbies" type="checkbox" value="tunning"
                %(checked-tunning)s
            > Auto Tunning
        </p>
        <p>
            <input type="submit" value="Submit">
        </p>
    </form>
    <p>
        Age: %(age)s<br>
        Hobbies: %(hobbies)s
    </p>
</body>
</html>
'''

def app(env, response):
    
    # 解析QUERY_STRING
    d = parse_qs(env['QUERY_STRING'])
    
    age = d.get('age', [''])[0] # 返回 age 对应的值
    hobbies = d.get('hobbies', []) # 以 list 形式返回所有的 hobbies
    
    # 防止脚本注入
    age = escape(age)
    hobbies = [escape(hobby) for hobby in hobbies]
    
    response_body = html% {
        'checked-software': ('', 'checket')['software' in hobbies],
        'checked-tunning': ('', 'checked')['tunning' in hobbies],
        'age': age or 'Empty',
        'hobbies': ','.join(hobbies or ['No Hobbies?'])
    }
    
    status = '200 OK'
    
    response_body = [
        ('Content-Type', 'text/html'),
        ('Content-Length', str(len(response_body)))
    ]
    
    start_response(status, response_headers)
    return [response_body]

httpd = make_server('', 8088, app)

httpd.serve_forever()

处理 POST 请求的动态网页

对于POST 请求,查询字符串是放在 HTTP 请求正文(request body)末尾的,不是显式在 url 中。请求正文在 env 字典变量中键为wsgi.input对应的值中,这是一个类似 file 的变量:

'wsgi.input': <_io.BufferedReader name=7>

我看源码看晕了还是没找到这个 name 具体是什么意思,经过 google 猜测这个应该是个标识符。

from wsgiref.simple_server import make_server
from cgi import parse_qs, escape

# html中form的method是post
html = """
<html>
<body>
   <form method="post" action="">
        <p>
           Age: <input type="text" name="age" value="%(age)s">
        </p>
        <p>
            Hobbies:
            <input
                name="hobbies" type="checkbox" value="software"
                %(checked-software)s
            > Software
            <input
                name="hobbies" type="checkbox" value="tunning"
                %(checked-tunning)s
            > Auto Tunning
        </p>
        <p>
            <input type="submit" value="Submit">
        </p>
    </form>
    <p>
        Age: %(age)s<br>
        Hobbies: %(hobbies)s
    </p>
</body>
</html>
"""

def application(environ, start_response):

    # CONTENT_LENGTH 可能为空,或者没有
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0

    request_body = environ['wsgi.input'].read(request_body_size)
    d = parse_qs(request_body)

    # 获取数据
    age = d.get('age', [''])[0] 
    hobbies = d.get('hobbies', []) 

    # 转义,防止脚本注入
    age = escape(age)
    hobbies = [escape(hobby) for hobby in hobbies]

    response_body = html % { 
        'checked-software': ('', 'checked')['software' in hobbies],
        'checked-tunning': ('', 'checked')['tunning' in hobbies],
        'age': age or 'Empty',
        'hobbies': ', '.join(hobbies or ['No Hobbies?'])
    }

    status = '200 OK'

    response_headers = [
        ('Content-Type', 'text/html'),
        ('Content-Length', str(len(response_body)))
    ]

    start_response(status, response_headers)
    return [response_body]

httpd = make_server('localhost', 8051, application)

httpd.serve_forever()

中间件

中间件位于 WSGI server 和 WSGI application 之间。所以对客户端来说,中间件扮演服务器;对服务器来说,中间件扮演客户端。在 Django 中wsgi 收到的数据用 request对象表示,要传给客户端的数据用 Httpresponse对象表示。

示例:

from wsgiref.simple_server import make_server

def application(environ, start_response):

    response_body = 'hello world!'

    status = '200 OK'

    response_headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(response_body)))
    ]

    start_response(status, response_headers)
    return [response_body]

# 中间件
class Upperware:
   def __init__(self, app):
      self.wrapped_app = app

   def __call__(self, environ, start_response):
      for data in self.wrapped_app(environ, start_response):
        yield data.upper()

wrapped_app = Upperware(application)

httpd = make_server('localhost', 8051, wrapped_app)

httpd.serve_forever()

--结束END--

本文标题: wsgi 协议

本文链接: https://www.lsjlt.com/news/180793.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • wsgi 协议
    前言 本来没打算这么早就学习 wsgi 的,因为想要学习python 是如何处理网络请求的绕不开 wsgi,所以只好先学习一下 wsgi。先对 wsgi 有个印象,到了学习 Django 运行方式以及如何处理网络请求数据的时候就会感觉很...
    99+
    2023-01-30
    协议 wsgi
  • Python Web开发中的WSGI协议
     在Python Web开发中,我们一般使用Flask、Django等web框架来开发应用程序,生产环境中将应用部署到Apache、Nginx等web服务器时,还需要uWSGI或者Gunicorn。一个完整的部署应该类似这样: Web ...
    99+
    2023-01-31
    协议 Python Web
  • 如何理解WEB开发中的Python WSGI协议
    今天就跟大家聊聊有关如何理解WEB开发中的Python WSGI协议,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Web应用程序开发Web应用程序的本质是什么简单描述Web应用程序的...
    99+
    2023-06-02
  • 网络层协议 ——— IP协议
    文章目录 IP协议基本概念IP协议格式分片与组装网段划分特殊的IP地址IP地址的数量限制私网IP地址和公网IP地址路由路由表生成算法 IP协议 IP协议全称为“网际互连协议(Internet Protocol)”,IP协议是...
    99+
    2023-08-18
    tcp/ip 网络 服务器 网络协议
  • 存储协议——FC协议讲解
    目录 FC基础概念 FC协议结构 FC通信 FC交换网络工作流程:(以封装SCSI协议为例) FC拓扑结构 FC协议的端口类型 FC适配器(FC HBA卡) FC基础概念 FC最开始为一种传输协议,由于其性能较高,逐渐发展到前端作为主机接...
    99+
    2023-09-18
    存储 网络 网络协议
  • 串行通信协议---HART协议
    实际应用中,HART协议是仅次于Modbus协议的最接近统一现场总线的标准,主要是在4~20mA电流信号上面叠加数字信号,物理层采用Bell 202标准的FSK技术成功实现模拟信号和数字信号双向同时通信而互不干扰。HART协议规定了传输的物...
    99+
    2023-08-21
    网络 网络协议 服务器
  • ICMP协议(Internet控制消息协议)
    系列文章目录 华为数通学习(3) 目录 前言 一,什么是ICMP协议? 二,实例:路由之间相互直连ping 三,了解ICMP报文 ​编辑 3.1,为什么要了解这个字段呢 四,ICMP重定向 (路径优化-绕路-最优路径) 五,ICMP错误报...
    99+
    2023-09-02
    网络 运维 信息与通信 网络协议
  • WebSocket协议
    文章目录 备注一、什么是WebSocket二、为什么要有WebSocket三、WebSocket特点3.1 全双工3.2 数据传输使用二进制帧3.3 服务地址沿用HTTP格式3.4 默认端口为...
    99+
    2023-09-02
    websocket 服务器 网络
  • http协议
    http协议 一 http协议概述 HTTP(hypertext transport protocol),即超文本传输协议。这个协议详细规定了浏览器和万维网服务器之间互相通信的规则。 HTTP就是一个通信规则,通信规则规定了客户端发送给服...
    99+
    2023-01-30
    协议 http
  • robots协议
    <div id="cnblogs_post_body" class="blogpost-body"><h3><strong>什么是robots.txt?</strong></h3>...
    99+
    2023-01-31
    协议 robots
  • OSI七层协议模型及其协议
    文章目录 一、OSI七层模型是什么?其协议有哪些?二、TCP/IP四层协议,TCP/IP五层协议,OSI七层协议是什么? 一、OSI七层模型是什么?其协议有哪些? 二、TCP/IP四层协议...
    99+
    2023-09-03
    网络 服务器 tcp/ip
  • 数据链路层协议 ——— 以太网协议
    文章目录 链路层解决的问题以太网协议认识以太网以太网帧格式认识MAC地址对比理解MAC地址和IP地址认识MTUMUT对IP协议的影响MTU对UDP协议的影响MTU对TCP协议的影响数据跨网络传输的过程 ARP协议ARP协议的作用...
    99+
    2023-08-18
    网络 tcp/ip 服务器 网络协议
  • PHP伪协议
    PHP伪协议 一、伪协议介绍 PHP伪协议,也是php支持的协议和封装协议。 常见的有: file:// 访问本地文件系统php:// 访问各个输入/输出流data:// 数据zip:// 压缩...
    99+
    2023-08-31
    php
  • PHP-伪协议
    伪协议 常用场景:文件包含 ,文本包含 常用的伪协议有 php://filter 读取文件源码 (协议可以对打开的数据流进行筛选和过滤,常用于读取文件源码) php://input 任意代码执行;这种伪协议用于读取原始的 HTTP POST...
    99+
    2023-09-01
    php 开发语言
  • TCP/IP协议
    ✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 TCP/IP协议应用层协议自定义应用层协议DNS 传输层协议端口号UDP协议UDP协...
    99+
    2023-08-18
    tcp/ip 网络 java
  • PHP 伪协议
    常见的php伪协议 file://                         访问本地文件系统php://                        访问输入输出流data://                       数...
    99+
    2023-09-03
    php 开发语言
  • WebSocket协议与HTTP协议的差异与联系
    引言:随着互联网的普及,Web应用的需求不断增加,为了实现实时交互和推送功能,新的通信协议WebSocket应运而生。而传统的HTTP协议也在这个过程中逐渐被WebSocket取代。本文将重点探讨WebSocket协议与HTTP协议的差异与...
    99+
    2023-10-21
    Http websocket 差异与联系
  • Python中的端口协议之基于UDP协议
    UDP协议:   1、python中基于udp协议的客户端与服务端通信简单过程实现   2、udp协议的一些特点(与tcp协议的比较)        3、利用socketserver模块实现udp传输协议的并发通信 -----------...
    99+
    2023-01-31
    协议 端口 Python
  • 【BBF系列协议】诊断协议规范(TR-143)
    目录 TR-143 启用网络吞吐量性能测试和统计监控 执行摘要 1.目的和范围 目的 范围 2 主动监测 ...
    99+
    2023-10-01
    网络协议 网络
  • 【网络编程·数据链路层】MAC帧/以太网协议/ARP协议/RARP协议
     需要云服务器等云产品来学习Linux的同学可以移步/-->腾讯云-->阿里云-->华为云...
    99+
    2023-09-16
    网络 计算机网络
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作