网络编程

网络编程

socket套接字编程

 

import 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.服务端添加兼容性代码(mac linux)
3.服务端重启频繁报端口占用错误
    from socket import SOL_SOCKET, SO_REUSEADDR
    server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 在bind前加
4.客户端异常关闭服务端报错的问题
    异常捕获
5.服务端链接循环
6.半连接池
    设置可以等待的客户端数量

 

黏包现象

 

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

 

struct模块

 

import struct
import json


d = {
    'file_name': '很好看.mv',
    'file_size': 1231283912839123123424234234234234234324324912,
    '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)

 

简易报头

 

import socket
import subprocess
import json
import struct

server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)

while True:
    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'))

 UDP代码编写

import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM)  # UDP协议
udp_sk.bind(('127.0.0.1',9000))  # 绑定地址
msg,addr = udp_sk.recvfrom(1024)
udp_sk.sendto(b'hi',addr)             
udp_sk.close() 


import socket
ip_port=('127.0.0.1',9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b'hello',ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)

 

posted @ 2022-01-12 21:28  XX_Bb  阅读(105)  评论(0编辑  收藏  举报