程序员

深入Python中的网络通信

作者:admin 2021-08-03 我要评论

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

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

 TCP/IP

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

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

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

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

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

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

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

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

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


客户端和服务器具体的

HTTP

图片出自《图解HTTP》书籍

三次握手,四次挥手

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

三次握手

四次挥手


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

Socket

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

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


将上面的图片整理步骤

1.建立连接:

  • 服务器:socket--->address--->bind--->listen--->accept
  • 客户端:socket--->connect

2.通信:收一发:recv(1024)<---send(byte)/sendall(byte)

3.关闭连接:close()

实现简单的通讯程序

服务端,server.py

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

客户端,client.py

  1. import socket 
  2.  
  3. #创建套接字 
  4. client = socket.socket() 
  5. #访问的服务器的ip和端口,用元组定义 
  6. ip_port = ("127.0.0.1", 8888) 
  7. #连接服务器主机 
  8. client.connect(ip_port) 
  9. #同一链接中,不断向服务器发生数据或请求 
  10. while True
  11.     #接收服务器发送或响应的数据 
  12.     data = client.recv(1024) 
  13.     #打印接收的数据;python3.x以上数据要编码(发送:data.enconde();接收后转为String类型:data.deconde()) 
  14.     print(data.decode()) 
  15.     messages = input("请输入发生或请求的数据(exit退出):"
  16.     client.send(messages.encode()) 
  17.     if messages == 'exit'
  18.         break 
  19.     ''
  20.     #接收服务器发送或响应的数据 
  21.     data = client.recv(1024) 
  22.     #打印接收的数据;python3.x以上数据要编码,发送enconde();接收deconde() 
  23.     print(data.decode()) 
  24.     ''
  25. #关闭连接 
  26. client.close() 

具体效果如下图所示。


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

  1. import socket 
  2. import threading 
  3. import random 
  4.  
  5.  
  6. def handle_client(): 
  7.     # 接受客户端请求链接 
  8.     client, address = server.accept() 
  9.     print("[*] Accept connection from: %s:%d" % (address[0], address[1])) 
  10.     messages = "Hello World!" 
  11.     client.send(messages.encode()) 
  12.     # 连续与当前连接的客户端通信 
  13.     while True
  14.         # 接受客户端数据 
  15.         request = (client.recv(1024)).decode() 
  16.         # 判断是否结束通信 
  17.         if request == 'exit'
  18.             break 
  19.         print("[*] Received from %s:%d : %s" % (address[0], address[1], request)) 
  20.         # 发送响应信息给客户端 
  21.         client.send((str(random.randint(1, 1000)) + ":" + "ACK!").encode()) 
  22.     # 关闭当前连接 
  23.     client.close() 
  24.  
  25.  
  26. if __name__ == "__main__"
  27.     # 创建套接字 
  28.     server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  29.     # 定义绑定ip和端口 
  30.     ip = '127.0.0.1' 
  31.     port = 8888 
  32.     # 绑定监听 
  33.     server.bind((ip, port)) 
  34.     # 设置最大连接数,默认为1 
  35.     server.listen(5) 
  36.     print("[*] Listening on %s:%d" % (ip, port)) 
  37.     # 循环开启线程,接受多个客户端的链接通信 
  38.     while True
  39.         # 创建一个线程 
  40.         client_handler = threading.Thread(target=handle_client) 
  41.         # 开启线程 
  42.         client_handler.start() 

 

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


本文转载自网络,原文链接:https://mp.weixin.qq.com/s/s62fd8WScXa4eQ5p18sC8A

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 十月更新修复了Windows 10的Ping of De

    十月更新修复了Windows 10的Ping of De

  • Windows10 UAC弹窗太烦但又不能关?教

    Windows10 UAC弹窗太烦但又不能关?教

  • 老大手把手教我玩 Git 变基!

    老大手把手教我玩 Git 变基!

  • 在Linux终端中展示幻灯片

    在Linux终端中展示幻灯片

腾讯云代理商
海外云服务器