热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

tcp通信程序发送图片_三十七、深入Python中的网络通信

「Author:Runsen」TCPIP计算机与网络设备两情侣要谈恋爱,相互通信,那么双方就必须有规则。基于相同的方法,不同

7003f06a25f509898dc00322ee0c17c1.png

「@Author:Runsen」

TCP/IP

计算机与网络设备两情侣要谈恋爱,相互通信,那么双方就必须有规则。基于相同的方法,不同的硬件、操作系统之间的通信,都需要一种规则。而我们就把这种规则称为协议(protocol)。

TCP/IP 是互联网相关各类协议族的总称。TCP/IP是指TCP和IP这两种协议。TCP/IP是在IP协议的通信过程中,使用到的协议族的统称。

TCP/IP协议族按层次分别为 应用层,传输层,网络层,数据链路层,物理层。可以按照不同的模型分4层或者是7层。

将TCP/IP分为5层,越靠下越接近硬件。

应用层:应用程序收到传输层的数据后,接下来就是要进行解读,解读必须要先规定好格式,而应用层就是规定应用程序的数据格式,主要协议有HTTP等。

传输层:该层为两台主机上的应用程序提供端到端的通信,传输层有两个传输协议为TCP(传输控制协议)和UDP(用户数据报协议),TCP是一个可靠的面向连接的协议,UDP是不可靠或者说无连接的协议。

网络层:决定如何将数据从发送方到接收方,是建立主机到主机的通信。

数据链路层:控制网络层与物理层之间的通信,主要功能是保证物理线路上进行可靠的数据传递。

物理层:该层负责物理传输,与链路有关,也与传输的介质有关。

c3bec92c961fdd18ea1653fd6e368e0e.png

客户端和服务器具体的

7811e02a12792e638899e49323888923.png
68f4b5d90690840b31a92b71290dbd95.png
HTTP

图片出自《图解HTTP》书籍

三次握手,四次挥手

TCP三次握手,四次挥手,Runsen也不会怎么说,就把网上最通俗的图放在下面 了,还是别看我很牛逼,牛逼的是做图的大佬。

三次握手

0c86747fa8cc14da5cf830bb33331369.png

四次挥手

9b1c3fda5c61357d5e0baf1d940b3e10.png

图片出自公众号(程序员小小溪),更多的名词和概念查找参考公众号程序员小小溪的文章~[1]

Socket

网络编程有一个重要的概念 socket(套接字),应用程序可以通过它发送或接收数据,套接字允许应用程序将 I/O 插入到网络中,并与网络中的其他应用程序进行通信。

我是来偷窥Python中的网络通信Socket,不小心偷窥到了一个非常不错的Socket好图

8a9e7ec604ed3fb4d117cef7b79e9d0e.png

将上面的图片整理步骤

1.建立连接:

  • 服务器:socket--->address--->bind--->listen--->accept

  • 客户端:socket--->connect

2.通信:收一发:recv(1024)

3.关闭连接:close()

实现简单的通讯程序

服务端,server.py

#导入socket模块
import socket
#创建套接字 或使用server = socket.socket()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#定义绑定的ip和端口,用元组定义
ip_port = ('127.0.0.1', 8888)
#绑定监听:bind(address),在AF_INET下,以元组(ip,port)的形式表示地址
server.bind(ip_port)
#设置最大连接数,默认为1
server.listen(5)
#不断接受连接:one by one
while True:
    print("等待数据连接中……")
    #接受客服端数据请求
    conn, address = server.accept()
    '''
    向客服端返回信息
    (注意:python3.x以上,网络数据的发送接收都是byte类型,
    发送接收String类型数据时需要对数据进行编码(发送:messages.enconde();接收后转为String类型:messages.deconde()),pyhon2.x则直接发送数据无须编码)
    '''
    messages = "连接成功!"
    conn.send(messages.encode())
    #计数信息条数
    count = 0
    #一个连接中,不断的接受客户端发来的数据
    while True:
        data = conn.recv(1024)
        #打印客户端发来的数据信息
        print(data.decode())
        #判断是否退出当前连接,等在下一个连接
        if data == b'exit':
          break
        #处理客户端数据(如:响应请求等)
        count = count + 1
        string = "第" + str(count) + "条信息:" + data.decode()
        conn.send(string.encode())
        #主动关闭连接
    conn.close()

客户端,client.py

import socket

#创建套接字
client = socket.socket()
#访问的服务器的ip和端口,用元组定义
ip_port = ("127.0.0.1", 8888)
#连接服务器主机
client.connect(ip_port)
#同一链接中,不断向服务器发生数据或请求
while True:
    #接收服务器发送或响应的数据
    data = client.recv(1024)
    #打印接收的数据;python3.x以上数据要编码(发送:data.enconde();接收后转为String类型:data.deconde())
    print(data.decode())
    messages = input("请输入发生或请求的数据(exit退出):")
    client.send(messages.encode())
    if messages == 'exit':
        break
    '''
    #接收服务器发送或响应的数据
    data = client.recv(1024)
    #打印接收的数据;python3.x以上数据要编码,发送enconde();接收deconde()
    print(data.decode())
    '''
#关闭连接
client.close()

具体效果如下图所示。

3282b6d90edd9397044eda3916ea4cfb.png

多线程通信

TCP服务器与多个TCP客户端同时进行连续通信,只需要通过threading创建多线程任务handle_client就可以了。

import socket
import threading
import random


def handle_client():
    # 接受客户端请求链接
    client, address = server.accept()
    print("[*] Accept connection from: %s:%d" % (address[0], address[1]))
    messages = "Hello World!"
    client.send(messages.encode())
    # 连续与当前连接的客户端通信
    while True:
        # 接受客户端数据
        request = (client.recv(1024)).decode()
        # 判断是否结束通信
        if request == 'exit':
            break
        print("[*] Received from %s:%d : %s" % (address[0], address[1], request))
        # 发送响应信息给客户端
        client.send((str(random.randint(1, 1000)) + ":" + "ACK!").encode())
    # 关闭当前连接
    client.close()


if __name__ == "__main__":
    # 创建套接字
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 定义绑定ip和端口
    ip = '127.0.0.1'
    port = 8888
    # 绑定监听
    server.bind((ip, port))
    # 设置最大连接数,默认为1
    server.listen(5)
    print("[*] Listening on %s:%d" % (ip, port))
    # 循环开启线程,接受多个客户端的链接通信
    while True:
        # 创建一个线程
        client_handler = threading.Thread(target=handle_client)
        # 开启线程
        client_handler.start()

5953fa3e8c60ac1c2a8361b245f0f0c8.png

python3.x以上,网络数据messages的发送接收都是byte类型,若要发送接收String类型数据时需要通过messages.enconde()对数据进行编码,接收后通过messages.deconde()转为String类型。pyhon2.x则直接发送数据无须编码。

本文已收录 GitHub,传送门~[2] ,里面更有大厂面试完整考点,欢迎 Star。

Reference

[1]

参考公众号程序员小小溪的文章: https://mp.weixin.qq.com/s/KK1dnNoHrbjMyuhQptaBAQ

[2]

传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100

更多的文章

点击下面小程序

5edf7595b34e8f10e15183083ea6e21e.png

- END -

8150ebb10aa07d8ace28e86328bfd188.png




推荐阅读
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • Unity与MySQL连接过程中出现的新挑战及解决方案探析 ... [详细]
  • Spring框架中枚举参数的正确使用方法与技巧
    本文详细阐述了在Spring Boot框架中正确使用枚举参数的方法与技巧,旨在帮助开发者更高效地掌握和应用枚举类型的数据传递,适合对Spring Boot感兴趣的读者深入学习。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
author-avatar
俺是个大老粗
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有