python实现 socket套接字---UDP&TCP

Socket

socket简称套接字,是支持TCP/IP的网络通信的基本操作单元,可以看作是不同主机之间的进程进行双向通信的端点,简单的说就是通信两方的一种约定,用套接字的相关函数来完成通信过程。
在这里插入图片描述

UDP

UDP是面向无连接、基于数据报的不可靠传输。

  1. python中UDP发送端传输的步骤为:
    导入模块
    创捷套接字
    数据传输
    关闭套接字

代码如下:

# 1. 导入模块
import socket
# 2.创建套接字
# socket.socket(协议类型,传输方式)
# 参数一:
# socket.AP_INET 使用IPV4
# socket.AF_INET6 使用IPV6
# 参数二:
# socket.SOCK_DGRAM 使用UDP传输方式(无连接)
# socket。SOCK_STREAM 使用TCP传输方式(有连接)
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 3.数据传输
# udp_socket.sendto(要发送的数据的二进制格式,对方的IP和端口号)
# 参数一:要发送的二进制格式
# 字符串转换成二进制格式 字符串.encode()
# 参数二:对方的IP地址和端口号 address类型
# 要求IP和端口号是一个元组:1)第一个元素的字符串类型的ip地址,2)完整类型的端口号
udp_socket.sendto('hello'.encode('gbk'), ('121.248.154.5', 8080))
# 3.关闭套接字
udp_socket.close()
  1. UDP接收端步骤为
  • 导入模块
  • 创建套接字
  • 发送数据
  • 接收数据
  • 解码数据
  • 输出显示接收到的二进制字符串
  • 关闭套接字
# 导入模块
import socket
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 绑定端口
addr = ('', 6666)
udp_socket.bind(addr)

# 发送数据
udp_socket.sendto('gram'.encode(), ('121.248.54.5', 8080))

# 接收数据
# recvfrom(1024)方法的作用:
# 1)从套接字中接受1024个字节的数据
# 2)此方法会造成程序的阻塞,等待另一台计算机发来数据
#    如果对方发数据了,recvfrom会自动解除阻塞
#    如果对方没有发送方数据,会一直等待
# rece_data= (b'hello',('192.168.171.30', 8080))
# rece_data[0 接受到的数据的二进制格式
# rece_data[1] 对方的ip和端口
# win默认gbk编码,linux默认utf-8编码
rece_data = udp_socket.recvfrom(1024)
rece_txt = rece_data[0].decode('gbk')
# 输出
print('来自:', rece_data[1], '的消息:', rece_txt)
# 关闭套接字
udp_socket.close()
  1. UDP广播
# 1.导入模块
import socket
# 2.创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 3.设置广播权限
# udp_socket.setsockopt(套接字,属性,属性值)
# SOL_SOCKET:当前的套接字
# SO_BROADCAST:广播属性
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)

# 4.发送数据
# 默认不允许发送广播
udp_socket.sendto('helloworld'.encode(), ('255.255.255.255', 8080))
# 5.关闭套接字
udp_socket.close()

TCP

一.TCP是面向有连接、基于字节流、可靠的传输方式。

  1. TCP面向连接:
    通信双方都必须先建立连接才能进行数据传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。
    双方间的数据传输都可以通过这一个连接进行,完成数据交换后,双方必须断开连接,以释放系统资源,这种连接是一对一的,因此TCP不适用与广播的应用程序,基于广播的应用程序使用UDP.
  2. TCP可靠传输
  • TCP采用应答机制
  • 超时重传
  • 错误校验
  • 流量控制和阻塞管理
  1. TCP和UDP不同点:
  • 面向连接
  • 有序数据传输
  • 重发丢失的数据包
  • 舍弃丢失的数据包
  • 无差错的数据传输
  • 阻塞/流量控制

二.TCP编程
TCP编程区分客户端和服务器:

  1. TCP客户端
"""
1. 导入模块
2. 创建套接字
3. 建立连接
4. 发送数据
5. 关闭连接
"""
# 1. 导入模块
import socket

# 2. 创建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 3. 建立连接
# connet是一个元组类型,ip地址和端口号
tcp_client_socket.connect(('121.248.154.5', 8080))
# 4. 发送数据 以及接受
tcp_client_socket.send('hello'.encode('gbk'))
# rece_data是服务器发送给客户端的信息的二进制,而udp中输入的还有发送方的ip和端口号
recv_data = tcp_client_socket.recv(1024)
recv_text = recv_data.decode('gbk')
print(recv_text)
# 5. 关闭连接
tcp_client_socket.close()

  1. TCP服务器
"""
1 创建套接字
2 bind绑定ip和port
3 开启监听,开启套接字为被动模式
4 等待客户端连接
5 收发数据
6 关闭连接
"""
import socket

# 1 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2 bind绑定ip和port
tcp_server_socket.bind(('', 8081))
# 3 开启监听,开启套接字为被动模式
# listen() 作用设置tcp_server_socket 套接字为被动监听模式,不能再主动发送数据,128是允许最大连接数
# window 下128有效,linux此数字无效
tcp_server_socket.listen(128)
# 4 等待客户端连接
# accept 开始接受客户端连接,程序会默认进入阻塞状态(等待客户端连接),如果由客户端连接后,程序自动解除阻塞
# recv_data返回有两个部分是一个元组
# 1)返回了一个新的套接字socket
# 2)返回了客户端的ip地址和端口号port
new_client_socket, client_ip_port = tcp_server_socket.accept()
print(new_client_socket, client_ip_port)
# 5 收发数据
# recv()会让程序再次阻塞
recv_data = new_client_socket.recv(1024)
recv_text = recv_data.decode('gbk')
print(recv_text)
# 不能呢在和当前的客户端通信了
new_client_socket.close()
# 6 关闭连接
tcp_server_socket.close()
  1. TCP服务器改进
"""
1 创建套接字
2 bind绑定ip和port
3 开启监听,开启套接字为被动模式
4 等待客户端连接
5 收发数据
6 关闭连接
"""
import socket

# 1 创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2 bind绑定ip和port
tcp_server_socket.bind(('', 8888))
# 3 开启监听,开启套接字为被动模式
# listen() 作用设置tcp_server_socket 套接字为被动监听模式,不能再主动发送数据,128是允许最大连接数
# window 下128有效,linux此数字无效
tcp_server_socket.listen(128)
# 4 等待客户端连接
# accept 开始接受客户端连接,程序会默认进入阻塞状态(等待客户端连接),如果由客户端连接后,程序自动解除阻塞
# recv_data返回有两个部分是一个元组
# 1)返回了一个新的套接字socket
# 2)返回了客户端的ip地址和端口号port

while True:
    new_client_socket, client_ip_port = tcp_server_socket.accept()
    print(new_client_socket, client_ip_port)

    # 5 收发数据
    # recv()会让程序再次阻塞
    while True:
        # 当接收到的数据为空的时候,表示客户端已经断开了,服务器也要断开
        recv_data = new_client_socket.recv(1024)
        if len(recv_data) != 0:
            recv_text = recv_data.decode('gbk')
            print(recv_text)
        else:
            print('客户端已经断开连接')
            break

# 不能再和当前的客户端通信了
new_client_socket.close()
# 6 关闭连接
tcp_server_socket.close()

"""
上面的程序只有当第一个客户端断开连接时第二个客户端才能和tcp服务器建立连接;
改进的话需要使用多线程
"""
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值