首页 > 其他分享 >(1)基于TCP协议的简单套接字(打电话模型)

(1)基于TCP协议的简单套接字(打电话模型)

时间:2023-06-23 17:35:24浏览次数:26  
标签:socket 0.1 TCP phone conn 接字 data 打电话 服务端

基于TCP协议的简单套接字(打电话模型)

【一】简单版1.0

服务端

# -*-coding: Utf-8 -*-
# @File : 服务端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体
# socket.SOCK_DGRAM : 报协议  ----> 每一次数据都是单独一部分
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)
# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用  ----> 服务器用
# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)
# 端口号:0-65535, 1024以前的都被系统保留使用
# phone.bind(('ip', port))
phone.bind(('127.0.0.1', 8080))

# 【3】.开机 -- 监听状态
# 5 :指的是半连接池的大小
phone.listen(5)
print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')
# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080

# 【4】.等待电话链接请求:拿到电话链接 conn
# 返回的是双向通路 --- 操作系统维持链接
# conn : 双向通路的链接
# client_addr : 客户端的iP和端口
conn, client_addr = phone.accept()
print('这是服务端的conn:>>>', conn)
# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>
print('这是服务端的client_addr:>>>', client_addr)
# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)

# 【5】.接收消息
# 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型
data = conn.recv(1024)
# 对接受的二进制数据进行解码
print('从客户端接受的数据:>>>>', data.decode('utf-8'))
# (5)从客户端接受的数据:>>>> is running for 发送信息
# 发消息 返回消息状态等信息
conn.send(data.upper())

# 【6】.关闭连接(必选的回收资源操作) conn
# 完成后断开连接
conn.close()

# 【7】.关机(可选操作)
phone.close()

客户端

# -*-coding: Utf-8 -*-
# @File : 客户端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.拨通服务端电话
# connect(('服务端ip', 服务端端口))
phone.connect(('127.0.0.1', 8080))
# (2)
# 【3】.通信
# send(二进制数据类型)
phone.send('is running for 发送信息'.encode('utf8'))

# 接受服务端返回的数据
data = phone.recv(1024)
# 打印返回的消息 解码
print(data.decode('utf8'))
# (6)IS RUNNING FOR 发送信息

# 【4】.关闭连接(必选的回收资源操作)
phone.close()

上面的问题就是信息只能传输一次

【二】升级版2.0

加上通信循环

【1】版本2.1 - 通信循环结束条件

服务端

# -*-coding: Utf-8 -*-
# @File : 服务端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体
# socket.SOCK_DGRAM : 报协议  ----> 每一次数据都是单独一部分
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)
# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用  ----> 服务器用
# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)
# 端口号:0-65535, 1024以前的都被系统保留使用
# phone.bind(('ip', port))
phone.bind(('127.0.0.1', 8080))

# 【3】.开机 -- 监听状态
# 5 :指的是半连接池的大小
phone.listen(5)
print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')
# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080

# 【4】.等待电话链接请求:拿到电话链接 conn
# 返回的是双向通路 --- 操作系统维持链接
# conn : 双向通路的链接
# client_addr : 客户端的iP和端口
conn, client_addr = phone.accept()
print('这是服务端的conn:>>>', conn)
# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>
print('这是服务端的client_addr:>>>', client_addr)
# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)

while True:
    # 【5】.接收消息
    # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型
    data = conn.recv(1024)

    if data.decode('utf-8') == 'q':
        break

    # 对接受的二进制数据进行解码
    print('从客户端接受的数据:>>>>', data.decode('utf-8'))
    # (5)从客户端接受的数据:>>>> is running for 发送信息
    # 发消息 返回消息状态等信息
    conn.send(data.upper())

# 【6】.关闭连接(必选的回收资源操作) conn
# 完成后断开连接
conn.close()

# 【7】.关机(可选操作)
phone.close()

客户端

# -*-coding: Utf-8 -*-
# @File : 客户端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.拨通服务端电话
# connect(('服务端ip', 服务端端口))
phone.connect(('127.0.0.1', 8080))
# (2)

while True:

    # 【3】.通信
    # send(二进制数据类型)
    msg = input('请输入需要发送的消息:>>>>').strip()

    phone.send(f'{msg}'.encode('utf8'))

    # 加入结束条件强制结束通信
    if msg == 'q':
        break

    # 接受服务端返回的数据
    data = phone.recv(1024)
    # 打印返回的消息 解码
    print(data.decode('utf8'))
    # (6)IS RUNNING FOR 发送信息

# 【4】.关闭连接(必选的回收资源操作)
phone.close()

输入的信息为空时,会阻塞通信

阻塞在服务端的反馈信息位置

客户端的接受信息不能为空

【2】版本2.2 - 用户输入信息为空时阻塞

客户端

# -*-coding: Utf-8 -*-
# @File : 客户端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.拨通服务端电话
# connect(('服务端ip', 服务端端口))
phone.connect(('127.0.0.1', 8080))
# (2)

while True:

    # 【3】.通信
    # send(二进制数据类型)
    msg = input('请输入需要发送的消息:>>>>').strip()

    phone.send(f'{msg}'.encode('utf8'))

    if len(msg) == 0: continue
    # 加入结束条件强制结束通信
    if msg == 'q':
        break

    # 接受服务端返回的数据
    data = phone.recv(1024)
    # 打印返回的消息 解码
    print(data.decode('utf8'))
    # (6)IS RUNNING FOR 发送信息

# 【4】.关闭连接(必选的回收资源操作)
phone.close()

服务端

# -*-coding: Utf-8 -*-
# @File : 服务端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体
# socket.SOCK_DGRAM : 报协议  ----> 每一次数据都是单独一部分
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)
# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用  ----> 服务器用
# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)
# 端口号:0-65535, 1024以前的都被系统保留使用
# phone.bind(('ip', port))
phone.bind(('127.0.0.1', 8080))

# 【3】.开机 -- 监听状态
# 5 :指的是半连接池的大小
phone.listen(5)
print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')
# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080

# 【4】.等待电话链接请求:拿到电话链接 conn
# 返回的是双向通路 --- 操作系统维持链接
# conn : 双向通路的链接
# client_addr : 客户端的iP和端口
conn, client_addr = phone.accept()
print('这是服务端的conn:>>>', conn)
# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>
print('这是服务端的client_addr:>>>', client_addr)
# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)

while True:
    # 【5】.接收消息
    # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型
    data = conn.recv(1024)

    if data.decode('utf-8') == 'q':
        break

    # 对接受的二进制数据进行解码
    print('从客户端接受的数据:>>>>', data.decode('utf-8'))
    # (5)从客户端接受的数据:>>>> is running for 发送信息
    # 发消息 返回消息状态等信息
    conn.send(data.upper())

# 【6】.关闭连接(必选的回收资源操作) conn
# 完成后断开连接
conn.close()

# 【7】.关机(可选操作)
phone.close()

客户端强制终止程序时,服务端会产生一系列问题

【3】版本2.3 - 用户信息为空时检测异常

  • 客户端
# -*-coding: Utf-8 -*-
# @File : 客户端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.拨通服务端电话
# connect(('服务端ip', 服务端端口))
phone.connect(('127.0.0.1', 8080))
# (2)

while True:

    # 【3】.通信
    # send(二进制数据类型)
    msg = input('请输入需要发送的消息:>>>>').strip()

    phone.send(f'{msg}'.encode('utf8'))

    if len(msg) == 0: continue
    # 加入结束条件强制结束通信
    if msg == 'q':
        break

    # 接受服务端返回的数据
    data = phone.recv(1024)
    # 打印返回的消息 解码
    print(data.decode('utf8'))
    # (6)IS RUNNING FOR 发送信息

# 【4】.关闭连接(必选的回收资源操作)
phone.close()
  • 服务端
# -*-coding: Utf-8 -*-
# @File : 服务端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体
# socket.SOCK_DGRAM : 报协议  ----> 每一次数据都是单独一部分
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)
# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用  ----> 服务器用
# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)
# 端口号:0-65535, 1024以前的都被系统保留使用
# phone.bind(('ip', port))
phone.bind(('127.0.0.1', 8080))

# 【3】.开机 -- 监听状态
# 5 :指的是半连接池的大小
phone.listen(5)
print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')
# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080

# 【4】.等待电话链接请求:拿到电话链接 conn
# 返回的是双向通路 --- 操作系统维持链接
# conn : 双向通路的链接
# client_addr : 客户端的iP和端口
conn, client_addr = phone.accept()
print('这是服务端的conn:>>>', conn)
# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>
print('这是服务端的client_addr:>>>', client_addr)
# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)

while True:
    # 【5】.接收消息
    # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型
    try:
        data = conn.recv(1024)

        if len(data) == 0:
            # 在 unix 系统里,一旦data收到的内容为空
            # 就意味着一种异常行为:客户端非法断开了链接
            break

        if data.decode('utf-8') == 'q':
            break

        # 对接受的二进制数据进行解码
        print('从客户端接受的数据:>>>>', data.decode('utf-8'))
        # (5)从客户端接受的数据:>>>> is running for 发送信息
        # 发消息 返回消息状态等信息
        conn.send(data.upper())
    except Exception as e:
        break

# 【6】.关闭连接(必选的回收资源操作) conn
# 完成后断开连接
conn.close()

# 【7】.关机(可选操作)
phone.close()

【三】迭代版3.0

  • 服务端应该满足的特点
    • 服务端一直提供服务
      • 在建立连接与结束链接之间再加上一层 循环
    • 服务端并发提供服务

【1】3.1 - 链接循环(循环建立链接)

  • 客户端
# -*-coding: Utf-8 -*-
# @File : 客户端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.拨通服务端电话
# connect(('服务端ip', 服务端端口))
phone.connect(('127.0.0.1', 8080))
# (2)

while True:

    # 【3】.通信
    # send(二进制数据类型)
    msg = input('请输入需要发送的消息:>>>>').strip()

    phone.send(f'{msg}'.encode('utf8'))

    if len(msg) == 0: continue
    # 加入结束条件强制结束通信
    if msg == 'q':
        break

    # 接受服务端返回的数据
    data = phone.recv(1024)
    # 打印返回的消息 解码
    print(data.decode('utf8'))
    # (6)IS RUNNING FOR 发送信息

# 【4】.关闭连接(必选的回收资源操作)
phone.close()
  • 服务端
# -*-coding: Utf-8 -*-
# @File : 服务端 .py
# author: Chimengmeng
# blog_url : https://www.cnblogs.com/dream-ze/
# Time:2023/6/20
import socket

# 【1】.买手机
# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体
# socket.SOCK_DGRAM : 报协议  ----> 每一次数据都是单独一部分
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)
# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用  ----> 服务器用
# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)
# 端口号:0-65535, 1024以前的都被系统保留使用
# phone.bind(('ip', port))
phone.bind(('127.0.0.1', 8080))

# 【3】.开机 -- 监听状态
# 5 :指的是半连接池的大小
phone.listen(5)
print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')
# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080

# 【4】.等待电话链接请求:拿到电话链接 conn
#  ---- 加上链接循环 ----> 循环建链接
while True:
    # 返回的是双向通路 --- 操作系统维持链接
    # conn : 双向通路的链接
    # client_addr : 客户端的iP和端口
    conn, client_addr = phone.accept()
    # (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>
    print('这是服务端的client_addr:>>>', client_addr)
    # (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)

    while True:
        # 【5】.接收消息
        # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型
        try:
            data = conn.recv(1024)

            if len(data) == 0:
                # 在 unix 系统里,一旦data收到的内容为空
                # 就意味着一种异常行为:客户端非法断开了链接
                break

            if data.decode('utf-8') == 'q':
                break

            # 对接受的二进制数据进行解码
            print('从客户端接受的数据:>>>>', data.decode('utf-8'))
            # (5)从客户端接受的数据:>>>> is running for 发送信息
            # 发消息 返回消息状态等信息
            conn.send(data.upper())
        except Exception as e:
            break

    # 【6】.关闭连接(必选的回收资源操作) conn
    # 完成后断开连接
    conn.close()

# 【7】.关机(可选操作)
phone.close()

标签:socket,0.1,TCP,phone,conn,接字,data,打电话,服务端
From: https://www.cnblogs.com/dream-ze/p/17499405.html

相关文章

  • (2)基于UDP协议的简单套接字
    基于UDP协议的简单套接字UDP协议----->数据报协议【一】简单版1.0【1】TCP协议所遇到的空数据问题是否存在?TCP协议是水流式协议:传入的数据不能为空,因为水是一直流的,在传输过程中不会对数据进行操作UDP协议是数据报协议:传入的数据可为空,在传输过程中UDP会对数据进行内......
  • (3)基于 TCP 协议实现服务端执行代码将结果反馈给客户端
    基于TCP协议实现服务端执行代码将结果反馈给客户端TCP协议是流式协议:在数据传输过程中大量数据的传入会造成数据的丢失和不完整解决数据传输过程中的问题:自定义协议应用:基于网络上传和下载文件socketserver:基于模块实现并发服务端满足的条件一直对外提供服务并......
  • (4)socket套接字使用模版
    socket套接字使用模版【一】客户端#-*-coding:Utf-8-*-#@File:客户端.py#author:Chimengmeng#blog_url:https://www.cnblogs.com/dream-ze/#Time:2023/6/22importjsonfromsocketimport*#解指定数据长度importstruct#创建socket对象client=s......
  • Python基于Socket编写TcpServer通信基本框架
    如下主要是实现单客户端连接通信,如下为Socket模块的常用属性和方法介绍。如要实现多客户端连接,请使用threading模块的多线程技术实现。属性:•socket.AF_INET:IPv4地址族。•socket.AF_INET6:IPv6地址族。•socket.SOCK_STREAM:TCP协议类型。•socket.SOCK_DGRAM:UDP协议类......
  • tcpcopy + tcpdump 离线回放
    简单来说,就是用tcpdump记录线上请求,用tcpcopy来重放,如下图所示: ......
  • fpga 以太网w5500 SPI传输80MHz FPGA verilog TCP客户端驱动源码,8个SOCKET都可用,SPI
    fpga以太网w5500SPI传输80MHzFPGAverilogTCP客户端驱动源码,8个SOCKET都可用,SPI频率80MHZ,硬件验证以通过。w5500ip核w5500软核,还有TCP服务端和UDP模式,联系联系我要那个,默认发TCP客户端。这个代码是用fpga驱动和使用w5500模块,做过优化,可能以达到w5500最高传输速度,学习必......
  • webView链接字串以及多点触摸问题
    packagefirsrdroid.tutorial.mywebview;importandroid.app.Activity;importandroid.os.Bundle;importandroid.webkit.WebView;importandroid.webkit.WebViewClient;publicclassUsingMyWebviewextendsActivity{WebViewmWebView;/**Calledwhentheact......
  • 设备Labview源码,给国内主机厂配套,采用Modus _tcp和西门子P L C通讯采集数据,研华P C I
    设备Labview源码,给国内主机厂配套,采用Modus_tcp和西门子PLC通讯采集数据,研华PCI板卡,工艺配方,数据曲线存储和追溯,是有志于上位机labview工程师参考好教程ID:27100606427875413......
  • 西门子、三菱、台达PLC手机组态软件,支持modbus协议的ModbusTesla手机组态软件 只支持m
    西门子、三菱、台达PLC手机组态软件,支持modbus协议的ModbusTesla手机组态软件只支持modbustcp,只要下位机支持标准的modbus协议就可以,不论PLC,变频器还是仪表等等。没有网口的可以加个串口服务器,软件版本1.37.6版本安卓手机组态软件可以和设备进行局域网通信,局域网通信时,只要安卓......
  • 浅谈TCP和UDP
    简介在计算机网络中,TCP(传输控制协议)和UDP(用户数据报协议)是两个常用的传输层协议。它们分别提供了可靠的数据传输和快速的数据传送,成为互联网世界中的双子星。本文将探讨TCP和UDP的特点、优势和应用场景,以及如何选择合适的协议来满足不同的需求。TCP定义英文名:TransmissionCon......