网络编程-2

传输层

1.PORT协议
2.TCP协议与UDP协议
	规定了数据传输所遵循的规则
ps:数据传输能够遵循的协议还有很多 TCP和UDP是较为常见的两个

TCP协议
    三次握手
        建立双向通道
        ps:洪水攻击
        	同时让大量的客户端朝服务端发送建立TCP连接的请求
    四次挥手
        断开双向通道
        中间的两步不能合并(因为需要有检查的时间1
"""
基于TCP传输数据非常的安全 因为有双向通道
	基于TCP传输数据 数据不容易丢失 不容易丢失的原因在于二次确认机制
		每次发送数据都需要返回确认消息 否则在一定的时间会反复发送
"""        
UDP协议
	基于UDP协议发送数据 没有任何的通道也没有任何的限制
    	UDP发送数据没有TCP安全(没有二次确认机制)
"""
TCP类似于打电话:有来有往 你一句我一句
UDP类似于发短息:只要发送了就完事 不管后果
"""

socket套接字

应用层
    主要取决于程序员采用什么策略和协议
    常见协议有:HTTP、HTTPS、FTP...
socket
基于文件类型的套接字家族
	套接字家族的名字:AF_UNIX
基于网络类型的套接字家族
	套接字家族的名字:AF_INET
"""
运行程序的时候 肯定是先确保服务端运行 之后为客户端
"""
import socket

# 1.创建一个socket对象
server = socket.socket()  # 括号内什么都不写 默认就是基于网络的TCP套接字
# 2.绑定一个固定的地址(ip\port)
server.bind(('127.0.0.1', 8080))  # 127.0.0.1本地回环地址(只允许自己的机器访问)
# 3.半连接池(暂且忽略)
server.listen(5)
# 4.开业 等待顾客
sock, address = server.accept()
print(sock, address)  # sock是双向通道 address是客户端地址
# 5.数据交互
sock.send(b'hello my brother')  # 朝客户端发送数据
data = sock.recv(1024)  # 接收客户端发送的数据 1024bytes
print(data)
# 6.断开连接
sock.close()  # 断链接
server.close()  # 关机


import socket

# 1.产生一个socket对象
client = socket.socket()
# 2.连接服务端(拼接服务端的ip和port)
client.connect(('127.0.0.1',8080))
# 3.数据交互
data = client.recv(1024)  # 接收服务端发送的数据
print(data)
client.send(b'hello man') # 朝服务端发送数据
# 4.关闭
client.close()

代码优化

1.send与recv
	客户端与服务端不能同时执行同一个
        有一个收 则另一个就是发
        有一个发 则另一个就是收
		不能同时收或者发!!!
2.消息自定义
	input获取用户数据即可(主要编码解码)
3.循环通信
	给数据交互环节添加循环即可
4.服务端能够持续提供服务
    不会因为客户端断开连接而报错
    异常捕获 一旦客户端断开连接 服务端结束通信循环 调到连接处等待
5.消息不能为空
	判断是否为空 如果是则重新输入(主要针对客户端)

'''以下主要针对mac linux'''
服务端频繁重启可能会报端口被占用的错
    from socket import SOL_SOCKET,SO_REUSEADDR
    server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)  # 在bind前加
客户端异常退出会发送空消息
	针对接收的消息加判断处理即可 

半连接池

server.listen(5)
	主要是为了做缓冲 避免太多无效等待

黏包问题

服务端代码
    sock.recv(1024)
    sock.recv(1024)
    sock.recv(1024)
客户端代码
    client.send(b'curry')
    client.send(b'oscar')
    client.send(b'kevin')
1.TCP特性
	流式协议:所有的数据类似于水流 连接在一起的
    	ps:数据量很小 并且时间间隔很多 那么就会自动组织到一起
2.recv
	我们不知道即将要接收的数据量多大 如果知道的话不会产生也不会产生黏包
    
"""
struct模块无论数据长度是多少 都可以帮你打包成固定长度
然后基于该固定长度 可以反向解析出真是长度

思路:
	1.先将真实数据的长度制作成固定长度 4
	2.先发送固定长度的报头
	3.再发送真实数据
	
	1.先接收固定长度的报头 4
	2.再根据报头解压出真实长度
	3.根据真实长度接收即可
"""
struct模块针对数据量特别大的数字没有办法打包!!!
posted @   初学者-11  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示