Python----网络编程基础 ---基于socket实现TCP协议与UDP协议的通信

本文介绍了Python基于socket实现的TCP和UDP协议通信。涵盖了网络编程的基础知识,如端口概念、网络连通性检查,以及TCP和UDP的特点、应用场景和创建步骤。通过示例展示了TCP和UDP的客户端和服务端如何进行数据传输。
摘要由CSDN通过智能技术生成

网络编程


Ubuntu命令
  查看ip:  ifconfig
   ping                                 查看网络连通性
   ping 127.0.0.1                 检查网络功能是否正常
   ping 本机网卡IP地址       检查网卡是否正常工作
   ping 远程主机IP/域名      检查与远程主机的连通性


端口基础
   定义:系统分配给网络应用程序的编号,用来区分数据传输
   网络程序必须要有端口号
   知名端口号0-1023
   动态端口号 1024-65535

检验指定端口网络连接情况:netstat -an | grep ":8080"

列出当前系统端口所对应的程序:   lsof -i [tcp/udp]:8080

扩展: netstat -anp | grep  ":8080"      查看指定端口的程序网络连接情况

扩展: ps -aux | grep  "python"           查看python的程序  

扩展:  kill -9 进程的PID                    关闭进程


 UDP

特点

  1.    无需确认对端是否存在,发送端随时可发送数据
  2.    无连接、资源开销小、速度块、单个数据包最大为64K
  3.    传输不可靠,容易丢失数据
  4.    没有流量控制,所有接受方需及时接收数据,否则会出现缓冲过慢,电脑卡死

使用场景

  •    音乐视频传输
  •    广播
  •    主要用在通讯质量要求不高的场景

创建步骤

   客户端:初始化,指定ip端口sendto发送,recvform接受,close关闭

#创建一个udp_licent
#初始化,ipv4,指定udp模式,绑定端口
#发送数据
#接受数据
#关闭套接字对象
import socket
import time

def main():
    #初始化
    udp_licent = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #发送数据
    udp_licent.sendto("要发送的数据".encode("utf-8"),('127.0.0.1',8080))
    #接受数据
    info = udp_licent.recvfrom(1024)  # 每次接受1024个字节数据
    print(info[0].decode("utf-8"))
    info = udp_licent.recvfrom(1024)   #每次接受1024个字节数据
    print(info[0].decode("utf-8"))  # 接受到的数据为二进制数据进行解码
    #关闭对象
    udp_licent.close()
    time.sleep(1)
if __name__ == '__main__':
    while True:
        main()


   服务端:初始化、端口复用、绑定端口、广播模式、接受、发送(广播模式255地址进行广播)、关闭

#创建一个udp_server
#初始化
    #复用端口
    #绑定端口
    #设置广播模式
#响应客户端
    #接受数据
    #发送数据
#关闭套接字
import socket
def main():
    #初始化
    udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    #复用端口
    udp_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
    #设置广播模式,发送时指定255.255.255.255
    udp_server.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,True)
    #绑定端口
    udp_server.bind(('',8080))
    #接受数据,收到数据为一个元组,0下标元素为数据,1号下标为发送者地址与端口
    info = udp_server.recvfrom(1024)   #每次接受1024个字节数据
    #接受数据时阻塞程序
    print(".............程序被阻塞.................")
    #发送者地址信息
    news="收到:%s"%info[0].decode("utf-8")
    print(news)
    #发送数据,使用接受到的信息可以给发送者回复
    udp_server.sendto(news.encode("utf-8"),info[1])
    #使用255.255.255.255地址可以进行广播发送,此时简写成发送者的端口
    #实际进行广播时,客户端要设置成与客户端广播一致的端口
    udp_server.sendto("进行广播".encode("utf-8"),('255.255.255.255',info[1][1]))
    #关闭服务器套接字
    udp_server.close()

if __name__ == '__main__':
    while True:
        main()

 

TCP

概述

  •    面向连接的、可靠的、基于字节流的传输层通信协议.

特点

  1. TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
  2. 先建立连接才可以进行数据传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输可靠传输,采用发送应答机制,超时重传,错误校验,流量控制和阻塞管理

创建步骤

   客户端:初始化、connect连接、send发送、recv接受,close关闭

import socket

# 创建tcp socket
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 目的信息
server_ip = input("请输入服务器ip:")
server_port = int(input("请输入服务器port:"))

# 链接服务器
tcp_client_socket.connect((server_ip, server_port))

# 提示用户输入数据
send_data = input("请输入要发送的数据:")

tcp_client_socket.send(send_data.encode("gbk"))

# 接收对方发送过来的数据,最大接收1024个字节
recvData = tcp_client_socket.recv(1024)
print('接收到的数据为:', recvData.decode('gbk'))

# 关闭套接字
tcp_client_socket.close()


   服务端:初始化、端口复用、绑定端口、监听模式、建立连接生成服务对象、服务对象send发送、服务对象recv接受、关闭服务                      对象、关闭服务端

import socket

# 创建socket
tcp_server_socket = socket(socket.AF_INET, socket.SOCK_STREAM)

# 本地信息
address = ('', 7788)

# 绑定
tcp_server_socket.bind(address)


# 设置监听
# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
# 128:表示最大等待连接数
tcp_server_socket.listen(128)

# 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket用来为这个客户端服务
# tcp_server_socket就可以省下来专门等待其他新客户端的链接
client_socket, clientAddr = tcp_server_socket.accept()

# 接收对方发送过来的数据
recv_data = client_socket.recv(1024)  # 接收1024个字节
print('接收到的数据为:', recv_data.decode('gbk'))

# 发送一些数据到客户端
client_socket.send("thank you !".encode('gbk'))

# 关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连接
client_socket.close()

 

UDP和TCP的区别

  1.   TCP面向连接不支持广播,UDP不是面向连接支持广播式
  2.   TCP需要连接,提供可靠数据传输且按序到达,但传输速度慢,UDP不需要连接,不保证可靠传输,但速度快
  3.   TCP适合发送大量数据,有流量控制,UDP适合发少量数据,没有流量控制

文件下载器示例代码

TCP服务端 参考代码如下:
import socket
import os

if __name__ == '__main__':
    # 创建tcp服务端socket
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置socket选项,防止程序退出端口不立即释放的问题
    tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口
    tcp_serve_socket.bind(("", 9090))
    # 设置监听,把主动套接字改成被动套接字,被动套接字只能接收客户端的连接请求,不能收发消息
    tcp_serve_socket.listen(128)
    # 循环接收客户端的连接请求, 提示:现在的下载是同步下载,一个用户下载完成以后另外一个用户才能下载
    while True:
        # 接收客户端的连接请求
        service_client_socket, ip_port = tcp_serve_socket.accept()
        # 代码执行到说明解阻塞,说明连接建立成功
        file_name_data = service_client_socket.recv(1024)
        # 解码数据
        file_name = file_name_data.decode("gbk")
        print(file_name, ip_port)
        if os.path.exists(file_name):
            # 文件存在
            with open(file_name, "rb") as file:
                # 读取文件数据
                while True:
                    file_data = file.read(1024)
                    if file_data:
                        # 发送文件数据给客户端
                        service_client_socket.send(file_data)
                    else:
                        break
        else:
            print("文件不存在")
        # 终止和客户端服务
        service_client_socket.close()
    # 终止提供处理连接请的服务
    tcp_serve_socket.close()
TCP客户端 参考代码如下:
import socket

if __name__ == '__main__':
    # 创建tcp客户端socket
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接
    tcp_client_socket.connect(("192.168.107.160", 9090))
    # 获取用户输入文件名
    file_name = input("请输入您要下载的文件名:")
    # 使用gbk进行编码
    file_name_data = file_name.encode("gbk")
    # 代码执行到此,说明连接建立成功
    tcp_client_socket.send(file_name_data)
    with open("/home/python/Desktop/" + file_name, "wb") as file:
        # 循环接收服务端发送的文件二进制数据
        while True:
            # 获取服务端文件数据
            file_data = tcp_client_socket.recv(1024)
            if file_data:
                # 写入到指定文件
                file.write(file_data)
            else:
                break

    # 关闭socket
    tcp_client_socket.close()
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值