Python socket之TCP通信、下载文件

news2024/11/26 21:43:43

TCP简介

TCP介绍

TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

TCP通信需要经过创建连接、数据传送、终止连接三个步骤。

TCP通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,“打电话”

TCP特点

1. 面向连接

通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。

双方间的数据传输都可以通过这一个连接进行。

完成数据交换后,双方必须断开此连接,以释放系统资源。

这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。

2. 可靠传输

1)TCP采用发送应答机制

TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功

2)超时重传

发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。

TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传

3)错误校验

TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

4) 流量控制和阻塞管理

流量控制用来避免主机发送得过快而使接收方来不及完全收下。

TCP与UDP的不同点

TCP

UDP

1

TCP的传输是可靠传输。

UDP的传输是不可靠传输。

2

TCP是基于连接的协议,在正式收发数据前,必须和对方建立可靠的连接。

UDP是和TCP相对应的协议,它是面向非连接的协议,它不与对方建立连接,而是直接把数据包发送出去

3

TCP是一种可靠的通信服务,负载相对而言比较大,TCP采用套接字(socket)或者端口(port)来建立通信。

UDP是一种不可靠的网络服务,负载比较小。

4

TCP和UDP结构不同,TCP包括序号、确认信号、数据偏移、控制标志(通常说的URG、ACK、PSH、RST、SYN、FIN)、窗口、校验和、紧急指针、选项等信息。

UDP包含长度和校验和信息。

5

TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。

6

TCP在发送数据包前在通信双方有一个三次握手机制,确保双方准备好,在传输数据包期间,TCP会根据链路中数据流量的大小来调节传送的速率,传输时如果发现有丢包,会有严格的重传机制,故而传输速度很慢。

UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

7

TCP支持全双工和并发的TCP连接,提供确认、重传与拥塞控制。

UDP适用于哪些系统对性能的要求高于数据完整性的要求,需要“简短快捷”的数据交换、需要多播和广播的应用环境。

tcp通信模型

udp通信模型中,在通信开始之前,不需要建立相关的链接,只需要发送数据即可,类似于生活中,“写信”

tcp通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,“打电话”

tcp注意点

  • tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器

  • tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机

  • tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的

  • 当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信

  • 当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务

  • listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的

  • 关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信,因为accept返回了新的套接字。

  • 关闭accept返回的套接字意味着这个客户端已经服务完毕

  • 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,就是recv()返回为空, sendto不能发送空消息,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

代码:

TCPServer:

import socket

tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("0.0.0.0", 8080))

# 将套接字将默认的主动模式改成被动模式(监听模式)
tcp_server.listen(128)

ret = tcp_server.accept()

print(ret)

tcp_server.close()

TCPClient:

import socket

tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))
tcp_client.send("hello,world!!!".encode("utf-8"))

tcp_client.close()

运行结果:

TCP服务端与客户端消息通信:

代码:

TCPServer:

import socket
import threading

tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("", 8080))

# 将套接字将默认的主动模式改成被动模式(监听模式)
tcp_server.listen(128)

client_socket, client_info = tcp_server.accept()


def deal_msg():
    while True:
        data = client_socket.recv(1024)
        print(data)
        # 当客户端关闭了连接,服务端的连接套接字也会继续执行接收函数,但返回的是空字符串,这时服务端的连接套接字就可以关闭了
        if data == "":
            break
    client_socket.close()


threading.Thread(target=deal_msg).start()

print(client_socket, client_info)

tcp_server.close()

TCPClient:

import socket
import time

tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))

while True:
    time.sleep(2)
    tcp_client.send("hello,world!!!".encode("utf-8"))

# tcp_client.close()

下载文件:

TCPDownloaderServer:

import socket
import threading

tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server.bind(("0.0.0.0", 8080))
tcp_server.listen(128)

tcp_client, clint_info = tcp_server.accept()


def send_file():
    with open("./test.txt", "rb") as fp:
        while True:
            byteData = fp.read(128)
            print(byteData)
            if byteData:
                tcp_client.send(byteData)
            else:
                break
        tcp_client.close()


threading.Thread(target=send_file).start()

tcp_server.close()

TCPDownloaderClient:

import socket

tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_client.connect(("192.168.1.12", 8080))

with open("./test2.txt", "wb") as fp:
    while True:
        data = tcp_client.recv(1024)
        print(data)
        if data.decode("utf-8") == "":
            break
        fp.write(data)

tcp_client.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手撕八大排序(上)

排序的概念及其引用: 排序的概念: 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有…

Linux上基于PID找到对应的进程名以及所在目录

Linux上基于PID找到对应的进程名以及所在目录前言找到进程的pid通过top命令查看通过 ps -ef |grep nignx进行查看通过端口号进行查看查看nginx进程目录前言 在一台新接触的服务器,却不熟悉搭建所在目录的时候,这时候就就可以通过ps查找进程,并…

巧用性格上的差异来组建团队

你好,我是得物 App 交易平台及中间件平台的 Team Leader Alan。 组建团队过程中,你有没有遇到过类似的场景:团队中某些人之间总是互相不对付、气场不合,不管是日常沟通中还是方案对齐,总是会出现面红耳赤的场面。 从…

Linux_线程概念

进程回顾 在学习线程之前,我们先回顾一下之前讲的进程概念 当我们创建一个进程,操作系统会将磁盘中的代码load到内存中,然后创建当前进程的task_struct(后面可能会用”PCB“或者”进程控制块“代替),创建…

egg+vue实现登录功能【解决vue中登录的潜在问题】

前后端登录功能实现前言一、cookie和session二、代码呈现1.egg部门代码2.vue代码过程前言 记忆在时间面前总是不堪一击! 本人的记录,下面内容仅供参考,如有什么什么,请自行解决。 一、cookie和session 不多赘述,详情…

大数据Hadoop教程-学习笔记03【Hadoop MapReduce与Hadoop YARN】

视频教程:哔哩哔哩网站:黑马大数据Hadoop入门视频教程教程资源: https://pan.baidu.com/s/1WYgyI3KgbzKzFD639lA-_g 提取码: 6666【P001-P017】大数据Hadoop教程-学习笔记01【大数据导论与Linux基础】【17p】【P018-P037】大数据Hadoop教程-学习笔记02【…

风险的定义以及CAPM 和 APT

文章目录风险定义:CAPMAPT(Arbitrage Pricing Theory)套利定价模型风险定义: 投资组合的收益率等于组合中各资产收益率的加权平均,但是投资组合的标准差并不等于组合中各资产标准差的加权平均,而是小于等于…

Git 详细教程

目录1.简介:2.安装Git3.Git 如何工作状态区域4.使用Git5.Git配置5.1 创建仓库 - repository5.2 配置5.2.1 --global5.2.2 检查配置6. 查看工作区的文件状态6.1什么是工作区6.2 如果显示乱码的解决方式7.在工作区添加单个文件8. 添加工作区文件到暂存区9. 创建版本10…

数据结构与算法(二)(Python版)

数据结构与算法(一)(Python版) 文章目录递归动规初识递归:数列求和递归三定律递归的应用:任意进制转换递归的应用:斐波那契数列递归调用的实现分治策略与递归优化问题和贪心策略找零兑换问题贪心…

RocketMQ-基本概念

主题(Topic) Apache RocketMQ 中消息传输和存储的顶层容器,用于标识同一类业务逻辑的消息。主题通过TopicName来做唯一标识和区分。 主题的作用主要如下: 定义数据的分类隔离: 在 Apache RocketMQ 的方案设计中&…

挚文集团短期内不适合投资,长期内看好

来源:猛兽财经 作者:猛兽财经 挚文集团(MOMO)在新闻稿中称自己是“中国在线社交和娱乐领域的领军企业”。 该公司旗下的陌陌是中国“陌生人社交网络”移动应用类别的领导者,并在2022年9月拥有超过1亿的月活跃用户。探…

Eotalk Vol.03:结合 API DaaS,让使用数据更方便

Eotalk 是由 Eolink CEO 刘昊臻发起的泛技术聊天活动,每期都会邀请一些技术圈内的大牛聊聊天,聊些关于技术、创业工作、投融资等热点话题。 Eotalk 的第 3 期,很高兴邀请到 Tapdata CEO TJ 唐建法,TJ 可以说是一位超级大咖&#x…

ESP32-C3 BLE5.0 扩展蓝牙名称长度的流程

蓝牙设备名称长度受限于蓝牙广播数据包的长度,如果广播数据包的长度不能包含完整的设备名称,则只显示短名称,其余不能容纳的部分将被截断。ESP32-C3 支持 BLE5.0,最大广播包长支持 1650 字节,可通过 esp_ble_gap_confi…

Windows下SecureCRT的下载、安装、使用、配置【Telnet/ssh/Serial】

目录 一、概述 二、SecureCRT的下载、安装 三、SecureCRT的使用  👉3.1 使用SSH协议连接Linux开发主机  👉3.2 使用Serial(串口)协议连接嵌入式开发板  👉3.3 使用Telnet协议连接嵌入式开发板 四、SecureCRT配置会话选项  🎨4…

将Nginx 核心知识点扒了个底朝天(九)

Nginx 如何实现后端服务的健康检查? 方式一,利用 nginx 自带模块 ngx_http_proxy_module 和 ngx_http_upstream_module 对后端节点做健康检查。 方式二(推荐),利用 nginx_upstream_check_module 模块对后端节点做健康检查。 Nginx 如何开启…

Homekit智能家居DIY一智能通断开关

智能通断器,也叫开关模块,可以非常方便地接入家中原有开关、插座、灯具、电器的线路中,通过手机App或者语音即可控制电路通断,轻松实现原有家居设备的智能化改造。 随着智能家居概念的普及,越来越多的人想将自己的家改…

SQL零基础入门学习(五)

SQL零基础入门学习(五) SQL零基础入门学习(四) SQL SELECT TOP, LIMIT, ROWNUM 子句 ####SQL SELECT TOP 子句 SELECT TOP 子句用于规定要返回的记录的数目。 SELECT TOP 子句对于拥有数千条记录的大型表来说,是非…

如何使用DevEco Studio创建Native C++应用

简介本篇主要介绍如何使用DevEco Studio for OpenAtom OpenHarmony (以下简称“OpenHarmony”)创建一个Native C应用。应用采用“Native C”模板,实现了通过Node-API调用C标准库的功能。本示例通过调用C标准库接口来演示调用过程,…

【macos游戏】RimWorld人工智能说书人控制的科幻殖民地模拟器

原文来源于黑果魏叔官网,转载需注明出处。由人工智能说书人控制的科幻殖民地模拟器。RimWorld控制了一艘太空客轮坠毁的三名幸存者,该飞船在所探索的空间边缘建造了一个殖民地。这款游戏的灵感来源是萤火虫太空西部的精神、对矮人堡垒的深入研究以及史诗…

Python数值方法及数据可视化

随机数和蒙特卡洛模拟求解单一变量非线性方程求解线性系统方程函数的数学积分常微分方程的数值解 等势线绘图和曲线: 等势线 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Dx_vals np.linspace(-5,5,20) y_vals …