TCP基础知识点

TCP基础知识点

TCP 特点:

  • 优点
  • 面向连接(这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。)
  • 传输可靠,不丢包。(TCP采用发送应答机制,超时重传,错误校验,流量控制和阻塞管理)
  • 缺点
  • 传输速度慢,占用系统资源高

TCP和UDP区别:

TCP 面向连接; UDP 是不面向连接;
TCP 提供可靠的数据传输,也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达; UDP 不保证可靠的数据传输,容易出现丢包情况;
TCP 需要连接传输速度慢,UDP 不需要连接传输速度快
TCP 不支持发广播; UDP 支持发广播
TCP 对系统资源要求较多,UDP 对系统资源要求较少。
TCP 适合发送大量数据,UDP 适合发送少量数据
TCP 有流量控制,UDP 没有流量控制

TCP网络程序流程:

在这里插入图片描述

TCP的三次握手,四次挥手:

在这里插入图片描述
SYN: 表示连接请求 ACK: 表示确认 FIN: 表示关闭连接 seq:表示报文序号 ack: 表示确认序号

图解流程图

第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

在这里插入图片描述

图解流程如下
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送。
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1。
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送。
第四次挥手:Client收到FIN后,接着发送一个ACK给Server,确认序号为收到序号+1。

客户端发送数据

# 客户端发送数据步骤
# 1. 初始化socket
# 2. 连接
# 3. 发送数据
# 4. 关闭
import socket


def main():
    """客户端步骤"""
    # 1.初始化socket
    socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2. 连接
    socket_client.connect(("127.0.0.1", 8081))

    # 3. 发送数据
    socket_client.send("我要发了".encode("utf-8"))

    socket_client.send("我再发".encode("utf-8"))

    # 4. 关闭
    socket_client.close()


if __name__ == '__main__':
    main()

客户端发送接收数据

# 客户端发送接收数据
# 1. 初始化socket
# 2. 连接
# 3. 发送数据
# 4. 接收数据
# 5. 关闭
import socket

def main():
    """tcp客户端"""
    # 1.初始化socket
    tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 连接
    tcp_client.connect(("127.0.0.1", 8081))

    # 3. 发送数据
    tcp_client.send("我要发了".encode("utf-8"))

    # 4. 接收数据
    tcp_client_data = tcp_client.recv(1024)

    print(tcp_client_data)
    print("解码:", tcp_client_data.decode("utf-8"))

    # 5.关闭
    tcp_client.close()

if __name__ == '__main__':
    main()

tcp服务器端

# tcp服务器端
# 1. 初始化socket
# 2. 绑定端口及地址
# 3. 设置 被 动模块,设置 最大等待的客户端
# 4. 接收用户的请求
# 5. 处理客户端的请求
# 6. 关闭
import socket
def main():
    """tcp服务器端"""
    # 1.初始化socket
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 绑定端口与地址
    tcp_server.bind(("", 8182))
    # 3. 设置 被 动
    tcp_server.listen(128)
    # 4. 接收用户的请求
    clinet, address = tcp_server.accept()
    print(clinet)
    print(address)
    # 处理
    clinet.send("我知道了".encode("utf-8"))

    data = clinet.recv(1024)
    print(data.decode("utf-8"))
    # 6.关闭
    clinet.close()
    tcp_server.close()
if __name__ == '__main__':
    main()

聊天机器人(没有添加多任务)

# 创建一个tcp服务器端
# 1. 初始化
# 2. 绑定端口
# 3. 设置被动模式
# 4. 循环接收用户的请求
# 5. 处理用户的请求
# 6. 关闭
import socket


def client_exec(client):
    """
    这个客户端的处理
    :param client: 客户端连接的对象
    :return: NONE
    """

    while True:

        # 判断客户端是否关闭了,判断发送过来的数据,如果是空的,那么退出循环,如果不是空的,那回个信息
        data = client.recv(1024)
        # 判断是否有数据
        if data:
            # 说明有数据n
            # 解析 数据
            data_decode = data.decode("utf-8")

            # 您的数据已收到
            send_data = "您的数据已收到%s" % data_decode
            client.send(send_data.encode("utf-8"))
        else:
            # 说明没有数据,
            # 退出循环
            break

        # 关闭客户端
        client.close()


def main():
    """聊天机器人"""
    # 1.初始化
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2. 绑定端口
    tcp_server.bind(("", 8181))

    # 3. 设置被动模式
    tcp_server.listen(128)

    # 4. 循环接收用户的请求
    while True:
        # 接收
        client, address = tcp_server.accept()

        # 处理用户的请求
        # 一个函数一个功能
        client_exec(client)

    # 关闭
    tcp_server.close()


if __name__ == '__main__':
    main()

文件下载器服务器

# 1. 创建tcp服务器端
# 1.1 初始化socket
# 1.2 绑定 端口
# 1.3 设置被 动 128
# 1.4 循环接收客户端的文件路径
# 1.5 客户端的处理
# 1.6 关闭
# 2. 循环接收客户端发过来的文件路径
# 3. 判断一下文件是否存在
# 4. 文件存在,读取文件内容,一次读1024字节,循环发送给客户端
# 5. 没有文件,终止
# 6. 关闭
import os
import socket


def client_exec(client):
    """
    客户端的处理
    :param client: 与客户端连接的对象
    :return: NONE
    """
    # 接收的路径
    file_path = client.recv(1024).decode("utf-8")

    # 判断文件是否存在
    # xx.if
    if os.path.exists(file_path):
        print("文件存在")
        # 说明路径存在
        # 打开文件,循环读取内容发送,一次读1024字节
        with open(file_path, 'rb') as f:
            # 循环读取我们的内容
            while True:
                # 一次读1024字节
                content = f.read(1024)
                # 判断当前的文件是否读完了
                if content:
                    # 说明有内容
                    # 发送
                    client.send(content)

                    print("发送了数据")

                else:
                    print("发送完毕")
                    # 说明没有内容
                    # 关闭
                    # 关闭客户端,函数结束
                    client.close()
                    return

    else:
        print("文件不存在")
        # 说明路径不存在

        client.close()

        # 终止当前的函数
        return

    # 最后进行关闭
    client.close()


def main():
    """文件下载服务器"""
    # 1. 创建tcp服务器端
    # 1.1 初始化socket
    socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 复用端口
    socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    # 1.2 绑定 端口
    socket_server.bind(("", 8082))

    # 1.3 设置被 动 128
    socket_server.listen(128)

    # 1.4 循环接收客户端的文件路径
    while True:
        client, address = socket_server.accept()
        # 1.5 客户端的处理
        # 一个函数一个功能
        client_exec(client)

    # 1.6 关闭
    socket_server.close()


if __name__ == '__main__':
    main()

文件下载客户端

# 1. 创建一个tcp客户端
# 2. 发送一个路径
# 3. 循环接收服务器端发送过来的数据
# 4. 判断当前的数据是否结束
# 5. 如果有数据,那么我保存到我们的下载的文件中
# 6. 没有数据,程序结束
import socket


def main():
    """文件下载客户端"""
    # 创建一个tcp客户端
    # 1.初始化socket
    tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2. 连接
    tcp_client.connect(("127.0.0.1", 8082))

    # 3. 发送数据
    tcp_client.send("./1.gif".encode("utf-8"))

    # 4. 循环接收我们的数据
    while True:
        # 接收的数据
        data = tcp_client.recv(1024)
        # 判断一下数据是否完毕
        if data:
            # 说明有数据
            # 保存到文件中
            with open("./1_back.gif", 'ab') as f:
                f.write(data)
        else:
            # 说明没有数据
            # 退出循环
            break

    # 5.关闭
    tcp_client.close()


if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值