python之tcp/udp重点笔记3

导读:本篇文章讲解 python之tcp/udp重点笔记3,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

python之tcp/udp重点知识整合

一 网络基础知识

  • 1 linux中网卡的开关命令

:sudo ifconfig 网卡名 up在
:sudo ifconfig 网卡名 down
在这里插入图片描述
i**p **:是32位,一段分8位,总共4段,例如192.168.128.128
一段最大位255,最小为0,再网络中除去最大的和最小的不能用外,其他的可以用。主机位 .0代表本网络 .255代表广播,所以不是有效的ip
一般最大的IP用于网路广播,最小的用于本机环回如上图的网卡为lo的显示的。

  • 2 端口
    1.按端口号划分
    公认端口(Well Known Ports)
    0~1023,它们紧密绑定于一些服务,通常这些端口的通讯明确表明了某种服务的协议,如:80端口对应与HTTP通信,21端口绑定与FTP服务,25端口绑定于SMTP服务,135端口绑定与RPC(远程过程调用)服务。
    注册端口(Registered Ports)
    1024~49151,它们松散的绑定于一些服务,也就是说有许多服务绑定于这些端口,这些端口同样用于其他许多目的,如:许多系统处理端口从1024开始 – 动态和/或私有端口(Dyanmic and /or Private Ports)49152~65535,理论上,不应为服务分配这些端口,通常机器从1024开始分配动态端口。例外:SUN的RPC端口从32768开始。
    2.按协议类型划分
    按协议类型划分可分为TCP端口、UDP端口、IP端口、ICMP(Internet控制消息协议)。
    TCP端口:
    即传输控制协议端口,需要在客户端和服务器之间建立连接,这样可以提供可靠的数据传输。常见的包括FTP的21端口,Telnet的23端口,SMTP的25端口,HTTP的80端口。
    UDP端口:
    即用户数据报协议端口,无需在客户端和服务器端建立连接,安全性得不到保障。常见的DNS的53端口,SNMP(简单网络管理协议)的161端口,QQ使用的8000和4000端口。
    保留端口:
    UNIX有保留端口号的概念,只有超级用户特权的进程才允许给它自己分配一个保留端口号。这些端口号介于1~1023之间,一些应用程序将它作为客户与服务器认证的一部分。
    那怎么打开和关闭端口呢?
    关闭端口号:iptables -A INPUT -p tcp –drop 端口号-j DROP
      iptables -A OUTPUT -p tcp –dport 端口号-j DROP
    打开端口号:iptables -A INPUT -ptcp –dport 端口号-j ACCEPT
    以下是linux打开端口命令的使用方法。
      nc -lp 23 &(打开23端口,即telnet)
      netstat -an | grep 23 (查看是否打开23端口)
    要注意的一点是,Linux打开端口命令打开的每一个端口,都需要有与之对应的监听程序才可以。

二 udp协议

  • 1 概念

书面解释:UDP 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。
小编翻译:这就像是写信一样,你给你哥发了一封信,首先你只需要知道你哥的一些信息,比如住址、姓名等,然后这个时候你哥不知道你给他信了这就是无连接的,不需要他知道就可以直接发信。他收没收到你也不知道,而且这个信还容易丢掉(这就是udp的不稳定性)丢了就丢了。没有重发机制(虽然你说你会再写的,没必要杠哈哈,你能保证上一个和这个一样吗)。

  • 2 代码创建
    A给B通信的时候,A发送消息给B时,A需要知道B的ip(用来识别网络中那个时B)还需要知道他的端口号port(用于识别发送消息给那个程序,一个端口只能被绑定一次。)
#导入包
import socket
#创建一个套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#绑定一个端口 不绑定的话,操作系统自动分配
#接收信息一段必须绑定,而且还需要让对方知道你的端口和ip
aim_ip = input("输入你要发送的目的ip")
# 端口必须为整型,这里用到了强转
port = int(input("输入你要发送的目的端口号"))
bind_port= int(input("输入你本地要绑定的端口号"))
local_addr = ("",bind_port)
# bind 这个函数接受的是个元组
udp_socket.bind(local_addr)
#发送消息
send_data = input("输入发送的消息")
# 这里发送的消息需要编码一下
#Python decode() 方法以 encoding 指定的编码格式解码字符串。默认编码为字符串编码。
# 这里指,发送信息给谁。所以要有端口和ip
udp_socket.sendto(send_data.encode("gbk"),(aim_ip ,port) )
# 这里的1024表示接受1024个字节也就是1kB,
# 返回的是一个元组(消息,(发送方的ip,发送方的端口))
recv_data = udp_socket.recvfrom(1024)
#得到的消息中有字符串中文的话需要解码
信息 = recv_data[0].decode("gbk")
对方ip 和端口 = recv_data[1]
# 关闭套接字
udp_socket.close()

总结流程:
在这里插入图片描述
socket是全双工的就是说可以同时收发
通信传输分为:单双工只能收或者发,半双工具备收发不能同时收发,全双工可以同时收发

三 tcp协议

  • 1 概念
  • 官方解释TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。
  • 小编解释:就好比打电话知道吧,先拨通电话,对方接通(这是连接),然后说话就好了,你说一句对方反应一句,如果对方某句话没听懂没反应,你在重复一遍(就是数据丢失后的数据重传,所以tcp是可靠传输)
  • 2 代码
作为服务器代码:
import socket
# 创建一个套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#绑定一个端口
local_addr = ("",端口号)
tcp_socket.bind(local_addr)
# 准备把被动连接listen函数在一般在调用bind之
#后-调用accept之前调用,它的函数原型是:
#include<sys/socket.h>
#int listen(int sockfd, int backlog)
#返回:0──成功, -1──失败
# 设置listen让服务器由主动变被动,等待客户端连接
#里面的参数与连接客户端个数有关,具体根据自己 的服务器性能,这里不做深究,大家自己研究。
tcp_socket.listen(128)
# 设置等待客户端连接accept返回一个新的套接字用来处理客户端的,还有客户端的地址
new_client_socket, client_addr = tcp_socket.accept()
# 用新的new_client_socket实现发送接受信息,然后tcp_socket套接字继续执行等待其他客户端连接
new_client_socket.send("1921年共产党成立".encode('gbk'))
# 或者接受消息这个时候可以用recv 或者recvfrom,因为recv只有内容,我们不需要地址,前面的accept获取过了。所以用recv
new_data = new_client_socket.recv(1024).decode('gbk'):


客户端开发
import socket
client_socket= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 可以不用绑定端口的
# 链接服务器
sever_mag = ("192.168.88.88", 8836)
client_socket.connect(sever_mag)
# 发送消息
send_data = input("输入发送的消息:")
client_socket.send(send_data.encode('gbk'))
# 接受消息
recv_data = client_socket.recv(1024).decode("gbk")

总结

在这里插入图片描述

四 tcp下载文件

原理
就是服务去读取文件,读取一部分,然后发送一部分,客户端接受到之后保存到文件就好了
来源码

import socket
import time
import os


def main():
    while True:
        try:
            # tcp_sever()
            tcp_client()
        except Exception as ex:
            print(ex, "等待5秒")

            time.sleep(5)


def tcp_sever():
    # 创建一个套接字
    sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定一个port
    sever_addr = ("", 8836)
    sever_socket.bind(sever_addr)
    # 设置为监听状态
    sever_socket.listen(128)

    # 等待接受
    while True:
        print("开始监听——————等待服务器来进行连接")
        new_client_socket, client_addr = sever_socket.accept()
        print("链接%s成功" % str(client_addr))
        # 接受消息
        while True:
            recv_data = new_client_socket.recv(1024)
            if recv_data == "下载文件".encode('gbk'):
            # 发送给对方文件名
                new_client_socket.send("1.txt".encode('gbk'))
                with open("1.txt",'rb')as f:
                	txt_data = f.readlines()
                for data in txt_data:
                # 读二进制发送二进制
                	new_client_socket.send(data)
            if not recv_data:
            print("对方断连接了---")
            break
            # 发送消息
        new_client_socket.close()
        print("为客户端服务完毕")
    # sever_socket.close()


def tcp_client():
    # 创建一个套接字
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 链接服务器
    sever_mag = ("192.168.42.83", 8836)
    tcp_socket.connect(sever_mag)
    # 发送数据
    while True:
        send_data = input("输入发送的消息:")
        tcp_socket.send(send_data.encode('gbk'))
        if send_data == "exit":
            break
        elif send_data == '下载文件':
            file_size = 0
            file_name = tcp_socket.recv(1024).decode("gbk")
            print("文件%s开始下载……" % file_name)
            file_data = tcp_socket.recv(1024)
            while file_data:
                with open(f"{file_name}", 'ab')as f:
                    f.write(file_data)
                file_size = os.path.getsize(file_name) / 1024
                print("文件大小为:%.2fkB" % file_size)
                file_data = tcp_socket.recv(1024)
            print("文件%s下载完毕  大小为:%.2fkB" % (file_name, file_size))
    # 关闭套接字
    tcp_socket.close()


if __name__ == '__main__':
    main()

注意点

  • 对于解堵塞

1 有消息发来的时候,程序会从recv这个解堵塞,继续执行程序
2 当客户端断开的时候,会产生一个空字符,可以通过判断收到的数据为空来判断连接已经断开了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119322.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!