Python打卡学习之网络编程——TCP与UDP

Python网络编程

TCP(复杂可靠)与UDP(简单不可靠)的区别

1) TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
2) TCP提供可靠的传输(有序,无差错,不丢失,不重复); UDP提供不可靠的传输。
3) TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
4) TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。

windows 下查看IP地址方法

  1. win+R
  2. cmd
  3. ipconfig

套接字可以同时收发,特性是全双工(可多个同时收发,电话),半双工只能接收或发送(对讲机),单工只能发(收音机)3

一,UDP

接受数据

import socket
def main():
    # 1创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2绑定一个本地信息
    localaddr = ("", 8080)
    udp_socket.bind(localaddr)
    while True:
        # 3接受数据
        recv_date = udp_socket.recvfrom(1024)
        # recv_date这个变量储存的是一个元组(接收到的数据,(发送方的IP,端口))
        recv_msg = recv_date[0]
        send_addr = recv_date[1]
        # 4打印接受数据,recv_msg接受到的是字节,需要解码成汉字用utf-8
        # print(recv_date)
        print("%s:%s" % (str(send_addr), recv_msg.decode("utf-8")))
    # 5关闭套接字
    udp_socket.close()

if __name__ == '__main__':
    main()

发送数据

import socket


def main():
    # 1.创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    # 2,从键盘获取数据数据
    while True:
        send_date = input("请输入要发送的内容:")
        udp_socket.sendto(send_date.encode("utf-8"), ("192.168.137.1", 8080))
    # 3,关闭套接字
    udp_socket.close()


if __name__ == '__main__':
    main()

二,聊天器实战(UDP)

import socket


def send(udp_socket):
    dest_ip = input("请输入对方的IP")
    dest_port = int(input("请输入对方的端口"))
    send_date = input("请输入要发送的消息")
    udp_socket.sendto(send_date.encode("utf-8"), (dest_ip, dest_date))


def receive(udp_socket):
    recv_date = udp_socket.recvfrom(1024)
    print("%s : %s" % (recv_date[1], recv_date[0].decode("utf-8")))

def main():
    # 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 绑定端口
    udp_socket.bind(("", 7789))
    print("=" * 50)
    print("欢迎来到梦码交流 1.0")
    print("1, 发送消息")
    print("2, 接收消息")
    print("3,退出系统")
    print("=" * 50)
    # while循环处理事情
    while True:
        op = input("请选择执行的操作: ")
        if op == '1':
            # 发送
            send(udp_socket)
        elif op == '2':
            # 接受并显示
            receive(udp_socket)
        elif op == '3':
            print("欢迎下次使用")
            break
        else:
            print("输入有误,请重新输入")


if __name__ == '__main__':
    main()

三,TCP

服务器端

  1. 创建socket对象 socket.socket(socket.AF_INET,socket.SOCK_STREAM)(监视套接字)
  2. 绑定一个IP地址和端口号bind((" ",8000)) //默认本地
  3. 服务端监听操作时刻注意是否有客户端请求
  4. 同意连接请求accept() #返回一个二元元组,第一个是建立新服务器套接字,第二个是客户端地址
  5. recv(1024)接收数据#设定一次可以接收1024字节大小
  6. print(data.decode())#传过来的字节流需要用decode()解码
  7. 关闭新建套接字和监视套接字
import socket


def main():
    # 创建套接字(监听套接字)
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定端口
    tcp_socket.bind(("", 8080))
    # 让默认套接字由主动改为被动(listen)
    tcp_socket.listen(128)
    # 使用while循环,从而为多个客户端服务
    while True:
        print("等待客户端连接的到来...")
        # 等待客户端连接的到来 accept,返回元组,第一个是服务套接字,第二个为客户端接口
        new_client_socket, client_addr = tcp_socket.accept()
        print("一个新的客户端已经到来 %s" % str(client_addr))

        # 再来个while循环为一个客户端服务多次
        while True:
            # 接受客户端发来的请求
            recv_date = new_client_socket.recv(1024)
            print("客户端发来的请求是:%s" % recv_date.decode("utf-8"))
            # 如果recv解堵塞,有两种方式
            # 客户端发来数据
            # 客户端调用close导致
            if recv_date :
                new_client_socket.send("请求已经收到。。".encode("utf-8"))
            else:
                break
        # 服务完一个客户端需要关闭服务套接字
        new_client_socket.close()


if __name__ == '__main__':
    main()

客户端

  1. import socket #导入模块
  2. SOCK_STREAM—TCP协议方式
  3. AF_INET----我的是ipv4地址
  4. 创建socket对象:指定传输协议 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  5. 建立连接发送连接请求 IP地址和端口号 s.connect((‘127.0.0.1’,8000))
  6. s.send(“你好”.encode()) #只能发送字节流需要用encode转码字符串成字节,不然无法发送文件
  7. 关闭套接字
import socket


def main():
    # 1.创建套接字
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2,连接服务器 connect
    tcp_socket.connect(("169.254.164.239", 8888))
    # 2,从键盘获取数据数据
    while True:
        send_date = input("请输入要发送的内容(输入0键退出):")
        if send_date == '0':
            break
        # send直接发送内容
        tcp_socket.send(send_date.encode("utf-8"))
    # 3,关闭套接字
    tcp_socket.close()


if __name__ == '__main__':
    main()

四,下载器实战(TCP)

客户端

import socket


def main():
    # 1创建套接字
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2获取服务器IP和端口
    # dest_id = input("请输入下载服务器的IP:")
    # dest_port = input("请输入下载服务器的端口:")
    # 3连接服务器
    tcp_socket.connect(("169.254.164.239", 6789))
    # 4获取下载文件名
    download_file_name = input("请输入要下载的文件名:")
    # 5将文件名发送给服务器
    tcp_socket.send(download_file_name.encode("utf-8"))
    # 6接受文件中的数据
    recv_date = tcp_socket.recv(1024)
    # 7如果成功接收到数据,保存数据到文件中
    if recv_date:
        with open("【新】" + download_file_name, "wb")as file:
            file.write(recv_date)
    # 8关闭套接字
    tcp_socket.close()


if __name__ == '__main__':
    main()

服务器端

import socket


def send_file_to_client(new_client_socket, client_addr):
    # 1,接收客户端需要下载的文件名
    file_name = new_client_socket.recv(1024).decode("utf-8")
    print("客户端%s需要下载文件:%s" % (client_addr, file_name))
    # 2,打开文件,读取数据
    file_content = None
    try:
        file = open(file_name, "rb")
        file_content = file.read()
        file.close()
    except Exception as ret:
        print("没有要下载的文件:%s" % file_name)
    # 3,发送文件数据给客户端
    if file_content:
        print("%s 文件发送成功" % file_name)
        new_client_socket.send(file_content)


def main():
    # 1,创建套接字
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2,绑定本地信息
    tcp_server_socket.bind(("", 6789))
    # 3,让默认套接字由主动变为被动
    tcp_server_socket.listen(128)
    while True:
        print("等待客户端连接的到来...")
        # 等待客户端连接的到来 accept,返回元组,第一个是服务套接字,第二个为客户端接口
        new_client_socket, client_addr = tcp_server_socket.accept()
        print("一个新的客户端已经到来 %s" % str(client_addr))
        # 5,调用发送文件函数
        send_file_to_client(new_client_socket, client_addr)
        # 6,关闭套接字
        new_client_socket.close()


if __name__ == '__main__':
    main()

结语

前面花了几天时间复习python基础语法和面向对象知识,现在开始除了每天上网课外,就会抽时间深入学习python相关知识,继续加油,奥里给!!

道友们可以加我的微信公众号 梦码城 ,接下来的日子里我会在公众号上发布各种与编程方面的总结学习知识,也会送各位小伙伴大量的学习资源,梦码城,期待你的加入

猜你喜欢

转载自blog.csdn.net/qq_45724216/article/details/106244486