socket套接字编程

一,socket套接字编程

1
2
3
4
5
6
要求:我们自己想写一款可以数据交互的程序
# 只要涉及到远程数据交互必须要操作OSI七层 所以有现成的模块直接实现
 
socket模块
     
架构启动肯定是先启动服务端再启动客户端<br><br>

简易代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
improt socket
"""
导入模块的两种方式
    import句式
    from...import...句式
第三方模块下载
    pip3 install 模块名==版本号 -i 仓库地址
"""
 
server = socket.socket()  # 默认就是基于网络的TCP传输协议     买手机
server.bind('127.0.0.1', 8080) # 绑定ip和port                      插电话卡 
server.listen(5# 半连接池                                     开机(过度)
sock,address = server.accept() # 监听                    三次握手的listen态
print(address)             # 客户端地址
data = sock.recv(1024)   # 接收客户端发送的消息       听别人说话
print(data)
sock.send(b'hello my big baby'# 给别人回话
sock.close()       # 挂电话
server.close()        # 关机
 
 
 
 
import socket
client = socket.socket()     # 买手机
client.connect(('127.0.0.1', 8080) # 拨号
# 说话
client.send(b'hello big DSB DSB DSB!!!)
# 听他说
data = client.recv(1024)
print(data)
client.close()

 

 

通信循环及代码

1
2
3
4
5
6
7
8
9
10
1.客户端校验消息不能为空
2.服务端添加兼容性代码(mac linux)
3.服务端重启频繁报端口占用错误
    from socket import SOL_SOCKET,SO_REUSEADDR
    server。setsockopt(SOL_SOCKET, SO_REUSEADDR, 1#在bind前加
4.客户端异常关闭服务端报错的问题
    异常捕获
5.服务端链接循环
6.半连接池
    设置可以等待的客户端数量

 

 

黏包现象

1
2
3
4
5
6
7
8
9
10
11
12
数据管道的数据没有被完全取出
     
TCP协议有一个特性
    """
    当数据量比较小 且时间间隔比较短的多次数据
    那么TCP会自动打包成一个数据包发送
    """
     
报头
    能够标识即将到来的数据具体信息
        eg:数据量多大
    # 报头的长度必须是固定的

struct模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import struct
import json
 
d ={
      'file_name : '很好看.mv',   
      'file_size': 893290378230472345
      'file_desc': '拍摄的很有心 真的很好看!!!',
      'file_desc2': '拍摄的很有心 真的很好看!!!'
}
 
d = json.dumps(d)
res = struct.pack('i', len(d))
print(len(res)
res1 = struct.unpack('i', res)[0]
print(res1)

 

 

简易版本报头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import socket
import subprocess
import json
import struct
 
 
server = socket.socket()
server.bind('172.0.0.1', 8080)
server.listen(5)
 
while Tuer:
    sock, address = server.accept
    while True:
        data = sock.recv(1024# 接收cmd命令
        command_cmd = data.decode('utf8')
        sub =subprocess.Popen(command_cmd,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        res = sub.stdout.read() + sub.stderr.read()  # 结果可能会很大
        # 1.制作报头
        data_first = struct.pack('i', len(res))
        # 2.发送报头
        sock.send(data_first)
        # 3.发送真实数据
        sock.send(res)
 
 
import socket
import struct
 
client = socket.socket()  # 买手机
client.connect('127.0.0.1', 8080)
 
while True:
    msg = input('请输入cmd命令>>>:').strip()
    if len(msg) == 0:
        continue
    client.send(msg.encode('utf8'))
    # 1.先接收固定长度为4的报头数据
    recv_first = client.recv(4)
    # 2.解析报头
     real_length = struct.unpack('i', recv_first)[0]
    # 3.接收真实数据
    real_data = client.recv(real_length)
    print(real_data.decode('gbk'))

 

 

cs架构的简易版本视频管理系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import socket
import json
import os
import struct
 
server = socket.socket
server.bind('127.0.0.1' , 8080)
server.listen(5)
 
while True:
    data_path = D:\linux\linux,day1.vmx.lck\视频\day03\视频
    movie_name_list = os.listdir(data_path)
    for i, j in enumerate(movie_name_list, 1):
        print(i, j)
    choice = input('请选择你要上传的视频》》》:').strip()
    if choice.isdigit():
        choice = int(choice)
        if choice in range(1, len(movie_name_list)+1):
            movie_name = movie_name_list[choice-1]
            movie_path = os.path.join(data_path, movie_name)
             data_dict = {
                'file_name': 'XXX老师合集.mp4',
                'desc': '这是非常重要的数据',
                'size': os.path.getsize(movie_path),
                'info': '下午挺困的,可以提神醒脑'
            }
            data_json = json.dumps(data_dict)
            # 2.制作字典报头
            data_first = struct.pack('i', len(data_json))
            # 3.发送字典报头
            client.send(data_first)
            # 4.发送字典
            client.send(data_json.encode('utf8'))
            # 5.发送真实数据
            with open(movie_path,'rb') as f:
                for line in f:
                    client.send(line)
                     
                     
# 1.先接收固定长度为4的字典报头数据
        recv_first = sock.recv(4)
        # 2.解析字典报头
        dict_length = struct.unpack('i', recv_first)[0]
        # 3.接收字典数据
        real_data = sock.recv(dict_length)
        # 4.解析字典(json格式的bytes数据 loads方法会自动先解码 后反序列化)
        real_dict = json.loads(real_data)
        # 5.获取字典中的各项数据
        data_length = real_dict.get('size')
        file_name = real_dict.get("file_name")
 
        recv_size = 0
        with open(file_name,'wb') as f:
            while recv_size < data_length:
                data = sock.recv(1024)
                recv_size += len(data)
                f.write(data)

  

 

posted @   殷国敏  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
点击右上角即可分享
微信分享提示