scoket模块 粘包问题 tcp协议特点 重启服务器会遇到地址被占用问题
scoket()模块函数用法
- import socket
- socket.socket(socket_family,socket_type,protocal=0)
- 获取tcp/ip套接字
- tcpsock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- 获取udp/ip套接字
- udpsock =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
服务端套接字函数
s.bind() 绑定(主机,端口号)到套接字
s.listen() 开始tcp监听
s.accept() 被动接受tcp客户的连接,(阻塞式)等待连接的到来
客户端套接字函数
s.connect() 主动初始化tcp服务器连接
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收tcp数据
s.send() 发送tcp数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.recvfrom() 接收udp数据
s.sendto() 发送udp数据
s.close() 关闭套接字
- 1 用打电话的流程快速描述socket通信
- 2 服务端和客户端加上基于一次连接的循环通信
- 3 客户端发送发空,卡主,证明是从那一个位置卡的
- 服务端:
- from socket import *
- phone =socket(AF_INET,SOCK_STREAM)
- phone.bind(('127.0.0.1',8081))
- phone.listen(5)
- conn,addr =phone.accept()
- while True:
- data =conn.recv(1024)
- print('server===>')
- print(data)
- conn.send(data.upper())
- conn.close()
- phone.close()
- 客户端:
- from socket import *
- phone=socket(AF_INET,SOCK_STREAM)
- phone.connect(('127.0.0.1',8081))
- while True:
- msg=input('>>: ').strip()
- phone.send(msg.encode('utf-8'))
- print('client===>')
- data=phone.recv(1024)
- print(data)
- 说明卡的原有:缓冲区为空recv就卡主,引出原理图
- 简单演示udp
- 服务端
- from socket import *
- phone =socket(AF_INET,SOCK_DGRAM)
- phone.bind(('127.0.0.1',8082))
- while True:
- msg,addr =phone.recvfrom(1024)
- phone.sendto(msg.upper(),addr)
- # 客户端
- from socket import *
- phone =socket(AF_INET,SOCK_DGRAM)
- while True:
- msg=input('>>: ')
- phone.sendto(msg.encode('utf-8'),('127.0.0.1',8082))
- msg,addr =phone.recvfrom(1024)
- print(msg)
- udp客户端可以并发演示
- udp客户端可以输入为空演示
socket 实验推演流程
基于TCP的套接字
tcp是基于连接的,必须先启动服务端,然后再启动客户端去连接服务端
tcp服务端
- from socket import *
- ss=socket() #创建服务器套接字
- ss.bind() #把地址绑定到套接字
- ss.listen() #监听连接
- inf_loop: #服务器无线循环
- cs=ss.accept() #接收客户端连接
- comm_loop: #通信循环
- cs.recv()/cs.send() #对话(接收与发送)
- cs.close() #关闭客户端套接字
- ss.close() #关闭服务器套接字(可选)
tcp客户端
- cs=socket() #创建客户套接字
- cs.connect() #尝试连接服务器
- comm_loop: #通讯循环
- cs.send()/cs.recv() #对话(发送/接收)
- cs.close() #关闭客户套接字
socket 通信流程与打电话流程类似
基于tcp协议通信的套接字
- import socket
- server = socket.socket() #买手机
- server.bind(('127.0.0.1',8080)) #插手机卡 bind((ip,port))
- server.listen(5) #开机 半整数池
- conn , addr =server.accept() #待机等待接电话
- print(conn) #双向通道
- print(addr) #地址 ('127.0.0.1', 52942)
- data = conn.recv(1024) #接听别人说话 只接收1024个字节 bytes
- print(data) #b'hello how much?'
- conn.send(b'hello big baby!') #跟别人说话
- conn.close() #关闭通信连接
- server.close() #关闭服务端
服务端
- import socket
- #t套接字对象
- client = socket.socket()
- client.connect(('127.0.0.1',8080)) #找服务器 拨电话
- client.send(b'hello how much?') #给服务器发信息
- data = client.recv(1024) #接收服务器发来的信息
- print(data)
- client.close() #关闭客户端
客户端
加上连接循环与通信循环
- import socket
- ip_port=('127.0.0.1',8081)#电话卡
- BUFSIZE=1024
- s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
- s.bind(ip_port) #手机插卡
- s.listen(5) #手机待机
- while True: #新增接收链接循环,可以不停的接电话
- conn,addr=s.accept() #手机接电话
- # print(conn)
- # print(addr)
- print('接到来自%s的电话' %addr[0])
- while True: #新增通信循环,可以不断的通信,收发消息
- msg=conn.recv(BUFSIZE) #听消息,听话
- # if len(msg) == 0:break #如果不加,那么正在链接的客户端突然断开,recv便不再阻塞,死循环发生
- print(msg,type(msg))
- conn.send(msg.upper()) #发消息,说话
- conn.close() #挂电话
- s.close() #手机关机
循环服务端
- import socket
- ip_port=('127.0.0.1',8081)
- BUFSIZE=1024
- s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- s.connect_ex(ip_port) #拨电话
- while True: #新增通信循环,客户端可以不断发收消息
- msg=input('>>: ').strip()
- if len(msg) == 0:continue
- s.send(msg.encode('utf-8')) #发消息,说话(只能发送字节类型)
- feedback=s.recv(BUFSIZE) #收消息,听话
- print(feedback.decode('utf-8'))
- s.close() #挂电话
循环客户端
重启服务器时可能会遇到
- OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
- 或者 OSError:[Errno 48] Address already in use
- 这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址(1 tcp三次握手,四次挥手 2 syn洪水攻击
3 服务器高并发情况下会有大量的time_wait状态的优化方法) #客户端没请求到服务器了 服务器要看一下自己是不会还有消息没法客户端- 解放方法:
加入一条socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #在bind前面加 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8080))
- 发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
- vi /etc/sysctl.conf
- 编辑文件,加入以下内容:
- net.ipv4.tcp_syncookies = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_tw_recycle = 1
- net.ipv4.tcp_fin_timeout = 30
- 然后执行 /sbin/sysctl -p 让参数生效。
- net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
- net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
- net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
- net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
- 方法二
方法二
tcp协议特点
- import socket
- server = socket.socket()
- server.bind(('127.0.0.1',8808))
- server.listen(5) #半连接池 等待连接的最大的客户端数
- conn,addr = server.accept()
- # data = conn.recv(1024)
- # print(data)
- #b'hellohellohello' 接收的小于1024的 所有的客户端发来的信息
- data = conn.recv(4)
- print(data)
- #b'hell'
- data = conn.recv(5)
- print(data)
- #b'ohell' #会先接收上次没接收完的信息
- data = conn.recv(5)
- print(data)
- #b'ohell' #会先接收上次没接收完的信息
- conn.close()
- server.close()
服务端
- import socket
- client = socket.socket()
- client.connect(('127.0.0.1',8808))
- client.send(b'hello')
- client.send(b'hello')
- client.send(b'hello')
- #tcp协议的优化特点 发送数据量小的间隔时间短 会一起发送
- #会将数据量比较小的并且时间间隔比较短的数据一次性打包发送给接收端
- client.close()
客户端
struct模块
- import struct
- data='sdkjfksdfjsdkfjksdjfkjdsk'
- #服务端
- res = struct.pack('i',len(data))
- print(len(res)) #4 会把多个字符的字符串 打包成只有4个的对象
- print(res) #b'\x19\x00\x00\x00'
- #客户端
- ret=struct.unpack('i',res) #解包成原来的 字符串个数 i 代表int 整形
- print(ret) #(25,)
- print(ret[0]) #
模拟ssh实现远程执行命令
- import socket
- import subprocess
- import struct
- import json
- server =socket.socket()
- server.bind(('127.0.0.1',8081))
- server.listen(5) #半连接池
- while True:
- conn ,addr =server.accept() #等待电话
- while True:
- try:
- data = conn.recv(1024).decode('utf-8')
- if len(data) == 0:break
- obj = subprocess.Popen(data,shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout = obj.stdout.read()
- stderr = obj.stderr.read()
- print(len(stderr+stdout))
- header_dic = {
- 'filename':'cls.av',
- 'len':len(stdout+stderr)
- }
- header_bytes = json.dumps(header_dic).encode('utf-8')
- #制作报头
- header = struct.pack('i',len(header_bytes))
- conn.send(header)
- conn.send(header_bytes)
- conn.send(stdout)
- conn.send(stderr)
- #conn.send(stdout+stderr) 字符串拼接 从新拷贝一份占内存
- # 和单独发也是一样的 间隔时间短的接收到的也是一起的
- except ConnectionResetError:
- break
- conn.close()
- server.close()
服务端
- import socket,struct,json
- client = socket.socket()
- client.connect(('127.0.0.1',8081))
- while True:
- msg = input('>>>: ').encode('utf-8')
- if len(msg)==0:continue
- client.send(msg)
- header = client.recv(4) #接收字典打包后的4个长度的字节 精确接收
- print(header,'这是报头的长度')
- head_len = struct.unpack('i',header)[0] #对这个头进行解包,获取原来的字典的字节数长度
- print(head_len,'这是字典的字节数')
- head_dic =json.loads(client.recv(head_len).decode('utf-8'))
- # 反序列化 接收字典的长度(精确接收)解码
- #得到字典
- print(head_dic,'这是字典')
- #对需要接受的数据 进行循环接收
- total_size = head_dic['len']
- recv_size=0
- res=b''
- while recv_size < total_size: #字符
- data = client.recv(1024) #每次接收到的信息
- res +=data
- recv_size +=len(data)
- print(res.decode('gbk'))
- client.close()
客户端
udp套接字
udp是无连接的,先启动那一端都不会报错
udp服务端
- ss=socket() #创建一个服务器的套接字
- ss.bind() #绑定服务器套接字
- inf_loop: #服务器无限循环
- cs=ss.recvfrom()/ss.sendto() #对话(接收与发送)
- ss.close() #关闭服务器套接字
udp客户端
- cs=socket() #创建客户端套接字
- comm_loop: #通信循环
- cs.sendto()/cs.recvfrom() #对话(发送/接收)
- cs.close() #关闭客户套接字
udp套接字简单实例
- 服务端
- import socket
- server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- server.bind(('127.0.0.1',8080))
- while True:
- data ,addr =server.recvfrom(1024)
- print(data)
- server.sendto(data.upper(),addr)
- 客户端
- import socket
- client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- server_addr=('127.0.0.1',8080) #服务端地址,通常写在配置文件中
- client.sendto(b'hello',server_addr)
udp 实现简易版本的qq
- import socket
- server=socket.socket(type=socket.SOCK_DGRAM)
- server.bind(('127.0.0.1',8080))
- while True:
- msg,addr =server.recvfrom(1024)
- print(addr,msg.decode('utf-8'))
- data=input('服务端回复:').encode('utf-8')
- server.sendto(data,addr)
服务端
- import socket
- client =socket.socket(type=socket.SOCK_DGRAM)
- server_addr =('127.0.0.1',8080)
- while True:
- msg = input('输入消息:')
- msg = '客服端1的消息:%s' % msg
- client.sendto(msg.encode('utf-8'),server_addr)
- data,addr =client.recvfrom(1024)
- print(data.decode('utf-8'))
客户端
- import socket
- client =socket.socket(type=socket.SOCK_DGRAM)
- server_addr =('127.0.0.1',8080)
- while True:
- msg = input('输入消息:')
- msg = '客服端2的消息:%s' % msg
- client.sendto(msg.encode('utf-8'),server_addr)
- data,addr =client.recvfrom(1024)
- print(data.decode('utf-8'))
客户端2
- import socket
- client =socket.socket(type=socket.SOCK_DGRAM)
- server_addr =('127.0.0.1',8080)
- while True:
- msg=input('输入消息:')
- msg='客服端3的消息:%s'%msg
- client.sendto(msg.encode('utf-8'),server_addr)
- data,addr =client.recvfrom(1024)
- print(data.decode('utf-8'))
客户端3
subprocess模块
- import socket
- import subprocess
- import struct
- '''
- 服务端必备三要素:
- 1 要有固定的ip和port
- 2 要能24小时提供服务
- 3 能承受高并发
- 并发:看上去像同时进行
- '''
- server=socket.socket()
- server.bind(('127.0.0.1',8080))
- server.listen(5)
- while True:
- conn,addr =server.accept()
- while True:
- try:
- cmd =conn.recv(1024).decode('utf-8')
- if len(cmd)==0:break #针对linux mac系统
- obj=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
- stdout=obj.stdout.read()
- stderr=obj.stderr.read()
- #制作固定报头
- header=struct.pack('i',len(stderr+stdout))
- #发送固定长度的报头
- conn.send(header)
- #发送真是数据
- conn.send(stdout)
- conn.send(stderr)
- except ConnectionResetError:
- break
- conn.close()
服务端
- import socket
- import struct
- client =socket.socket()
- client.connect(('127.0.0.1',8080))
- while True:
- cmd =input('>>:').encode('utf-8')
- if len(cmd)==0:continue
- client.send(cmd)
- header=client.recv(4)
- #解析报头获取真是数据的长度
- total_size=struct.unpack('i',header)[0]
- recv_size=0
- data=b""
- while recv_size<total_size:
- res=client.recv(1024)
- recv_size+=len(res)
- data+=res
- print(data.decode('gbk'))
客户端
socketserver模块 实现并发 基于tcp的套接字,关键字就是两个循环,一个是连接循环,一个通信循环
socketserver模块中分两大类:server类(解决连接问题)和request类(解决通信问题)
基于tcp的socketserver自定义的类中的
1 self.server即套接字对象
2 self.request即一个连接
3 self.client_address即客户端地址
基于udp的socketserver自定义的类中的
1 self.request是一个元组(第一个元素是客户端发来的数据,第二部分是服务端的udp套接字对象),
如(b'adsf', <socket.socket fd=200, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('127.0.0.1', 8080)>)
2 self.client_address即客户端地址
- import socket
- client =socket.socket()
- client.connect(('127.0.0.1',8080))
- while True:
- client.send(b'hello world')
- data= client.recv(1024)
- print(data)
tcp客户端
- import socketserver
- class MyBaby(socketserver.BaseRequestHandler):
- def handle(self):
- #通信循环
- while True:
- #self.request相当于你的conn通信对象
- data= self.request.recv(1024) #收消息
- print(data)
- self.request.send(data.upper())
- if __name__ == '__main__': #通道循环
- server = socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyBaby)
- server.serve_forever()
tcp服务端
- import socket
- import time
- client =socket.socket(type=socket.SOCK_DGRAM)
- server_addr=('127.0.0.1',8080)
- while True:
- client.sendto(b'hello world',server_addr)
- data,addr =client.recvfrom(1024)
- print(data,addr)
- time.sleep(1)
udp客户端
- import socketserver
- class MyBaby(socketserver.BaseRequestHandler):
- def handle(self):
- #通讯循环
- while True:
- #self.request 相当于conn通讯对象
- data,sock =self.request #收消息
- print(data)
- print(sock)
- sock.sendto(data.upper(),self.client_address) #self.client_address 客户端地址
- if __name__ == '__main__':
- server=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyBaby)
- server.serve_forever()
udp服务端
基于tcp文件上传
- import socket
- import struct
- import json
- server = socket.socket()
- server.bind(('127.0.0.1', 8080))
- server.listen(5)
- while True:
- conn, addr = server.accept()
- while True:
- try:
- # 接收报头
- header = conn.recv(4)
- # 解析报头获取字典长度
- header_len = struct.unpack('i', header)[0]
- # 接收字典
- header_bytes = conn.recv(header_len)
- header_dic = json.loads(header_bytes.decode('utf-8'))
- print(header_dic)
- # 循环接收文件存储到本地
- file_size = header_dic.get('file_size')
- file_name = header_dic.get('file_name')
- recv_size = 0
- # 文件操作
- with open(file_name, 'wb')as f:
- # 循环接收文件
- while recv_size < file_size:
- data = conn.recv(1024)
- f.write(data)
- recv_size += len(data)
- print(header_dic.get('msg'))
- except ConnectionResetError:
- break
- conn.close()
服务端
- import socket
- import os
- import json
- import struct
- client = socket.socket()
- client.connect(('127.0.0.1', 8080))
- # 文件大小
- file_size = os.path.getsize(r'E:\代码存放位置\第八周\莫文蔚-偷情.mp3')
- # 文件名字
- file_name = '歌曲名:偷情- 歌手:莫文蔚.mp3'
- # 定义一个字典
- d = {
- "file_name": file_name,
- "file_size": file_size,
- "msg": '注意身体哦'
- }
- data_bytes = json.dumps(d).encode('utf-8')
- # 制作字典的报头
- header = struct.pack('i', len(data_bytes))
- # 发送报头
- client.send(header)
- # 发送字典
- client.send(data_bytes)
- # 发送真实数据
- with open(r'E:\代码存放位置\第八周\莫文蔚-偷情.mp3', 'rb')as f:
- for line in f:
- client.send(line)
客户端
- import json
- res = {'name': '他说大帅比'}
- # print(json.dumps(res,ensure_ascii=False)) #{"name": "他说大帅比"}
- print(json.dumps(res)) # {"name": "\u4ed6\u8bf4\u5927\u5e05\u6bd4"}
- '''
- TCP
- 三次握手
- 可靠协议,流式协议
- 粘包问题的产生:
- 1.接收方:
- 我不知道我要接受的数据的总长度
- 2.发送方:
- 由于TCP协议的内部优化算法negle
- 1.会将数据量比较的小的并且时间间隔比较短的数据一次性打包发送
- UDP
- 数据报协议
- 没有双向通道
- 1.UDP协议不存在粘包问题
- 2.客户端可以发空
- 3.udp可以实现并发的效果
- 4.服务端不存在,也不影响客户端朝服务端发送数据
- TCP/UDP
- TCP:打电话
- UDP:发短信
- SocketServer模块
- 1.能够实现并发效果
- 并发:看起来像同时运行就能称之位并发
- 2.udp在使用的时候,多个客户端要有一些io操作
- 不然容易卡死
- 并发编程
- 操作系统发展史
- 多道技术:
- - 空间上的复用(多个程序共一套硬件设备,它是多道技术实现时间上的复用的基础,
- 不然还要去硬盘读数据)
- - 时间上的复用(单个cpu的电脑上,起多个应用程序。cpu快速切换,给人的感觉是同时运行)
- cpu两种情况下才会切换:(先保存当前程序的运行状态)
- - 一个任务占用cpu时间过长或被操作系统强行剥夺走cpu的执行权限(比起串行效率反而降低)
- - 一个任务执行过程中遇到io操作,也会被操作系统强行剥夺走cpu的执行权限(比起串行效率提高)
- 并发:看上去像同时进行的
- 并行:同时运行
- 补充:单核的计算机不可能实现并行!
- '''
scoket模块 粘包问题 tcp协议特点 重启服务器会遇到地址被占用问题的更多相关文章
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
- 网络编程 --- subprocess模块,struct模块,粘包,UDP协议,socket_server模块
目录 subprocess模块 struct模块 粘包 UDP协议 socket_server模块 subprocess模块 作用: 1.可以帮你通过代码执行操作系统的终端命令 2.并返回终端执行命令 ...
- (day27)subprocess模块+粘包问题+struct模块+ UDP协议+socketserver
目录 昨日回顾 软件开发架构 C/S架构 B/S架构 网络编程 互联网协议 socket套接字 今日内容 一.subprocess模块 二.粘包问题 三.struct模块 四.UDP 五.QQ聊天室 ...
- (网络编程)基于tcp(粘包问题) udp协议的套接字通信
import socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...
- 【转】Netty之解决TCP粘包拆包(自定义协议)
1.什么是粘包/拆包 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的消 ...
- Netty之解决TCP粘包拆包(自定义协议)
1.什么是粘包/拆包 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的消 ...
- socket模块粘包现象理解以及解决思路
粘包现象: 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送端为了将多个发往接收端的 ...
- socker通信-struct模块-粘包问题
Socket概念 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对 ...
- Wireshark抓包分析TCP协议
版权声明:本文为作者原创文章,可以随意转载,但必须在明确位置表明出处!!! 之前有一篇文章介绍了http协议「初识http协议」, http协议协议是基于tcp协议的,所以作者觉得有必要针对tcp ...
随机推荐
- Ioc容器与laravel服务容器初探
一.Ioc容器 某天,小J心血来潮,决定建造一艘星舰,这艘星舰要搭载"与众不同最时尚,开火肯定棒"的电磁炮.于是他写了一个星舰类: class ElectromagneticGun ...
- AcWing:177. 噩梦(bfs)
给定一张N*M的地图,地图中有1个男孩,1个女孩和2个鬼. 字符“.”表示道路,字符“X”表示墙,字符“M”表示男孩的位置,字符“G”表示女孩的位置,字符“Z”表示鬼的位置. 男孩每秒可以移动3个单位 ...
- 7. 使用Hystrix实现微服务的容错处理
使用Hystrix实现微服务的容错处理 7.1. 实现容错的手段 7.1.1. 雪崩效应 在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整 ...
- Google 插件的使用
每次看英文网页或者文档的时候总会碰到不认识单词,就想能不能选中单词就可以显示翻译?于是就安装Google浏览器的翻译插件,总的来说,蛮繁琐的. 1.先安装谷歌访问助手 (1.)直接百度谷歌访问助手 ( ...
- PHP中的src32
crc32() 函数计算一个字符串的 crc32 多项式. 该函数可用于验证数据的完整性. 语法 crc32(str 参数 描述 string 必需.规定要计算的字符串. 说明 生成 string 参 ...
- mysql数据库引擎——MyISAM,InnoDB
作为一个java web开发人员,对于mysql数据库掌握到具体比较这两类引擎的差异也蛮拼的,下面就介绍一下我在工作中积累的对这两类引擎的理解. MyISAM: 如果不更改mysql配置文件(my.i ...
- goland 可用注册码(license)
N757JE0KCT-eyJsaWNlbnNlSWQiOiJONzU3SkUwS0NUIiwibGljZW5zZWVOYW1lIjoid3UgYW5qdW4iLCJhc3NpZ25lZU5hbWUiO ...
- React Native 常用第三方组件
React-Native-Elements 一组开发RN的UI工具包(强烈推荐)
- css3弹性盒子display:flex
先看上面的代码,解释一下意思,看你能认识多少(后面有注释): .container { display: flex; //弹性布局 flex-direction: column; //容器内项目的排列 ...
- 机器学习 - 算法 - 集成算法 - 分类 ( Bagging , Boosting , Stacking) 原理概述
Ensemble learning - 集成算法 ▒ 目的 让机器学习的效果更好, 量变引起质变 继承算法是竞赛与论文的神器, 注重结果的时候较为适用 集成算法 - 分类 ▒ Bagging - bo ...