天道酬勤,学无止境

解决粘包问题


目录

  • 一、解决粘包问题(low版)
    • 1.1 服务端
    • 1.2 客户端
    • 1.3 为何low
  • 二、补充struct模块
    • 2.1 简单使用
  • 三、解决粘包问题(Nick版)
    • 3.1 使用struct模块创建报头
    • 3.2 服务端
    • 3.3 客户端
  • 四、TCP协议粘包问题分析
    • 4.1 服务端
    • 4.2 客户端
    • 4.3 服务端
    • 4.4 客户端


一、解决粘包问题(low版)

问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据。

1.1 服务端

import socket, subprocess

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind(('127.0.0.1', 8000))
server.listen(5)

while True:
    conn, addr = server.accept()

    print('start...')
    while True:
        cmd = conn.recv(1024)
        print('cmd:', cmd)

        obj = subprocess.Popen(cmd.decode('utf8'),
                               shell=True,
                               stderr=subprocess.PIPE,
                               stdout=subprocess.PIPE)

        stdout = obj.stdout.read()

        if stdout:
            ret = stdout
        else:
            stderr = obj.stderr.read()
            ret = stderr

        ret_len = len(ret)

        conn.send(str(ret_len).encode('utf8'))

        data = conn.recv(1024).decode('utf8')

        if data == 'recv_ready':
            conn.sendall(ret)

    conn.close()

server.close()

1.2 客户端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 8000))

while True:
    msg = input('please enter your cmd you want>>>').strip()

    if len(msg) == 0: continue

    client.send(msg.encode('utf8'))
    length = int(client.recv(1024))

    client.send('recv_ready'.encode('utf8'))

    send_size = 0
    recv_size = 0

    data = b''

    while recv_size < length:
        data = client.recv(1024)
        recv_size += len(data)

    print(data.decode('utf8'))

1.3 为何low

程序的运行速度远快于网络传输速度,所以在发送一段字节前,先用send去发送该字节流长度,这种方式会放大网络延迟带来的性能损耗

二、补充struct模块

2.1 简单使用

124-解决粘包问题-struct模块参数.png?x-oss-process=style/watermark

import struct
import json

# 'i'是格式
try:
    obj = struct.pack('i', 1222222222223)
except Exception as e:
    print(e)
    obj = struct.pack('i', 1222)
print(obj, len(obj))
'i' format requires -2147483648 <= number <= 2147483647
b'\xc6\x04\x00\x00' 4
res = struct.unpack('i', obj)
print(res[0])
1222

三、解决粘包问题(Nick版)

解决粘包问题的核心就是:为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据。

3.1 使用struct模块创建报头

import json
import struct

header_dic = {
    'filename': 'a.txt',
    'total_size':
    111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222223131232,
    'hash': 'asdf123123x123213x'
}

header_json = json.dumps(header_dic)

header_bytes = header_json.encode('utf-8')
print(len(header_bytes))

# 'i'是格式
obj = struct.pack('i', len(header_bytes))
print(obj, len(obj))
223
b'\xdf\x00\x00\x00' 4
res = struct.unpack('i', obj)
print(res[0])
223

3.2 服务端

from socket import *
import subprocess
import struct
import json

server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8000))
server.listen(5)

print('start...')
while True:
    conn, client_addr = server.accept()
    print(conn, client_addr)

    while True:
        cmd = conn.recv(1024)

        obj = subprocess.Popen(cmd.decode('utf8'),
                               shell=True,
                               stderr=subprocess.PIPE,
                               stdout=subprocess.PIPE)

        stderr = obj.stderr.read()
        stdout = obj.stdout.read()

        # 制作报头
        header_dict = {
            'filename': 'a.txt',
            'total_size': len(stdout) + len(stderr),
            'hash': 'xasf123213123'
        }
        header_json = json.dumps(header_dict)
        header_bytes = header_json.encode('utf8')

        # 1. 先把报头的长度len(header_bytes)打包成4个bytes,然后发送
        conn.send(struct.pack('i', len(header_bytes)))
        # 2. 发送报头
        conn.send(header_bytes)
        # 3. 发送真实的数据
        conn.send(stdout)
        conn.send(stderr)

    conn.close()

server.close()

3.3 客户端

from socket import *
import json
import struct

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8000))

while True:
    cmd = input('please enter your cmd you want>>>')

    if len(cmd) == 0: continue

    client.send(cmd.encode('utf8'))

    # 1. 先收4个字节,这4个字节中包含报头的长度
    header_len = struct.unpack('i', client.recv(4))[0]

    # 2. 再接收报头
    header_bytes = client.recv(header_len)

    # 3. 从包头中解析出想要的东西
    header_json = header_bytes.decode('utf8')
    header_dict = json.loads(header_json)
    total_size = header_dict['total_size']

    # 4. 再收真实的数据
    recv_size = 0
    res = b''
    while recv_size < total_size:
        data = client.recv(1024)

        res += data
        recv_size += len(data)

    print(res.decode('utf8'))

client.close()

四、TCP协议粘包问题分析

1.nagle算法规定,TCP协议会将数据量较小、时间间隔短的数据合并为一条发送给客户端

4.1 服务端

from socket import *

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

conn, addr = server.accept()

# 正确做法,客户端制作报头
# res1 = conn.recv(5)
# print('第一次;', res1)

# res2 = conn.recv(5)
# print('第二次;', res2)

# res3 = conn.recv(4)
# print('第三次;', res3)


# low方法+客户端的睡眠
res1 = conn.recv(1024)
print('第一次;', res1)

res2 = conn.recv(1024)
print('第二次;', res2)

res3 = conn.recv(1024)
print('第三次;', res3)

4.2 客户端

from socket import *
import time

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))

client.send(b'hello')
client.send(b'world')
client.send(b'nick')
# 服务端收到b'helloworldnick'

client.send(b'hello')
time.sleep(0.2)
# 服务端收到b'hello'

client.send(b'world')
time.sleep(0.2)
# 服务端收到b'world'

client.send(b'nick')
# 服务端收到b'nick'

2.接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

4.3 服务端

# _*_coding:utf-8_*_
__author__ = 'nickchen121'
from socket import *
ip_port = ('127.0.0.1', 8080)

TCP_socket_server = socket(AF_INET, SOCK_STREAM)
TCP_socket_server.bind(ip_port)
TCP_socket_server.listen(5)

conn, addr = TCP_socket_server.accept()

data1 = conn.recv(2)  # 一次没有收完整
data2 = conn.recv(10)  # 下次收的时候,会先取旧的数据,然后取新的

print('----->', data1.decode('utf-8'))
print('----->', data2.decode('utf-8'))

conn.close()

4.4 客户端

# _*_coding:utf-8_*_
__author__ = 'nickchen121'
import socket
BUFSIZE = 1024
ip_port = ('127.0.0.1', 8080)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
res = s.connect_ex(ip_port)

s.send('hello feng'.encode('utf-8'))
标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 聊聊TCP的粘包、拆包以及解决方案
    聊聊TCP的粘包、拆包以及解决方案 TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中,比如RPC框架、Netty等。如果你的简历中写了类似的技术或者你所面试的公司使用了相关的技术,被问到该面试的几率会非常高。 TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中,比如RPC框架、Netty等。如果你的简历中写了类似的技术或者你所面试的公司使用了相关的技术,被问到该面试的几率会非常高。 今天这篇文章就带大家详细了解一下TCP的粘包和拆包以及解决方案。 什么是粘包? 在学习粘包之前,先纠正一下读音,很多视频教程中将“粘”读作“nián”。经过调研,个人更倾向于读“zhān bāo”。 如果在百度百科上搜索“粘包”,对应的读音便是“zhān bāo”,语义解释为:网络技术术语。指TCP协议中,发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。 TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。 为什么UDP没有粘包? 粘包拆包问题在数据链路层、网络层以及传输层都有可能发生。日常的网络应用开发大都在传输层进行,由于UDP有消息保护边界,不会发生粘包拆包问题,因此粘包拆包问题只发生在TCP协议中 粘包拆包发生场景 因为TCP是面向流,没有边界
  • netty 解决TCP粘包与拆包问题(一)
    netty 解决TCP粘包与拆包问题(一) 参考文章: (1)netty 解决TCP粘包与拆包问题(一) (2)https://www.cnblogs.com/kabi/p/6115099.html 备忘一下。 来源:https://blog.csdn.net/jazz2013/article/details/115281446
  • Socket编程(网络编程)中TCP粘包的实例,含代码演示
    利用网络通信中,经常会出现粘包的问题,围绕着这个问题说原因和解决的蛮多帖子的,但是给出粘包代码的就好少,为了便于大家更好的理解粘包的问题,这里对客户端和服务器端出现的粘包问题进行模拟,以方便更好的理解这个问题的出现原因。在开始之前还是需要理解几个基础概念。 如果需要源代码请点击此处下载 1、什么是粘包? 粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。只有TCP有粘包现象,UDP不会。 2、哪里会发生粘包? 其实粘包主要分为两个方面,客户端和服务器端都可能会出现: a、客户端发生:当连续发送数据时,由于tcp协议的nagle算法,会将较小的内容拼接成大的内容,一次性发送到服务器端,因此造成粘包 b、服务器端发生:当发送内容较大时,由于服务器端的recv(buffer_size)方法中的buffer_size较小,不能一次性完全接收全部内容,因此在下一次请求到达时,接收的内容依然是上一次没有完全接收完的内容,因此造成粘包现象。 好了说了这些之后,我们简单通过一个图来介绍下我们要模拟的粘包的场景:简单说就是客户端向服务器端不停的发送两个包,一个数据包的内容是一个整形的数:4,另一个包是一个字符串:你好! 理想情况下,我们应该是客户端发送什么,发送多少服务器端就接收对应数量的数据: 然而,当我们加快客户端的发送速度时
  • 详述 Java NIO 以及 Socket 处理粘包和断包方法
    文章目录 Java NIO通道缓冲区代码示例第一部分第二部分 选择器 Socket 处理粘包 & 断包问题第一个问题:对于粘包问题的解决第二个问题:对于断包问题的解决示例代码 Java NIO NIO 是 New I/O 的简称,是 JDK 1.4 新增的功能,之所以称其为 New I/O,原因在于它相对于之前的 I/O 类库是新增的。由于之前老的 I/O 类库是阻塞 I/O,New I/O 类库的目标就是要让 Java 支持非阻塞 I/O,所以也有很多人喜欢称其为 Non-block I/O,即非阻塞 I/O。 NIO 的文件读写设计颠覆了传统 IO 的设计,采用『通道』+『缓存区』使得新式的 I/O 操作直接面向缓存区。NIO 弥补了原来同步阻塞 I/O 的不足,它在标准 Java 代码中提供了高速的、面向块的 I/O。通过定义包含数据的类,以及通过以块的形式处理这些数据,NIO 不用使用本机代码就可以利用低级优化,这是原来的 I/O 包所无法做到的。 通道 在 NIO 中,通道用Channel表示,网络数据通过Channel读取和写入。通道与流的不同之处在于通道是双向的,流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类),而通道可以用于读、写或者二者同时进行。因为Channel是全双工的,所以它可以比流更好地映射底层操作系统的
  • 网络编程解决黏包现象
    个人感悟:首先我觉的要想学好一门语言不论是是什么语言:java , C ,python ,PHP,都要弄明白网络请求与响应,过程,osi模型等,我觉的这个最基础的 ,但是今天我需要解决的是 网络交互时发生的"黏包"问题,行了不啰嗦了让我们进入正题吧。 黏包现象 让我们基于tcp先制作一个远程执行命令的程序(命令ls -l ; lllllll ; pwd) 这块我们需要注意下 res=subprocess.Popen(cmd.decode('utf-8'), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 的结果的编码是以当前所在的系统为准的,如果是windows,那么res.stdout.read()读出的就是GBK编码的,在接收端需要用GBK解码 且只能从管道里读一次结果 同时执行多条命令之后,得到的结果很可能只有一部分,在执行其他命令的时候又接收到之前执行的另外一部分结果,这种显现就是黏包 那么我们现在来实现个黏包现象吧 看我是怎么解决的的基于tcp协议实现的黏包tcp - server #_*_coding:utf-8_*_ from socket import * import subprocess ip_port=('127.0.0.1',8888) BUFSIZE=1024 tcp_socket
  • 粘包问题
    目录一、什么是粘包?二、TCP发送数据的四种情况三、粘包的两种情况3.1 服务端3.2 客户端3.3 服务端3.4 客户端四、补充问题一:为何TCP是可靠传输,udp是不可靠传输五、补充问题二:send(字节流)和recv(1024)及sendall一、什么是粘包?注意:只有TCP有粘包现象,UDP永远不会粘包,为何,且听我娓娓道来。首先需要掌握一个socket收发消息的原理发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。怎样定义消息呢?可以认为对方一次性write/send的数据为一个消息,需要明白的是当对方send一条信息的时候,无论底层怎样分段分片,TCP协议层会把构成整条消息的数据段排序完成后才呈现在内核缓冲区。例如基于TCP的套接字客户端往服务端上传文件,发送时文件内容是按照一段一段的字节流发送的,在接收方看了,根本不知道该文件的字节流从何处开始,在何处结束
  • python入门教程11-03 (python语法入门之socket通信)
    本章主要讲述Python中实现socket通信,因为socket通信的服务端比较复杂,而且客户端非常简单,所以客户端基本上都是用sockct模块实现,而服务端用有很多模块可以使用,干货在后面,一起来看看吧。Socket概念Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。基于TCP协议的socketserver端import socketsk = socket.socket()sk.bind((‘127.0.0.1’,8898)) #把地址绑定到套接字sk.listen() #监听链接conn,addr = sk.accept() #接受客户端链接ret = conn.recv(1024) #接收客户端信息print(ret) #打印客户端信息conn.send(b’hi’) #向客户端发送信息conn.close() #关闭客户端套接字sk.close() #关闭服务器套接字(可选)client端import socketsk = socket.socket() # 创建客户套接字sk.connect((‘127.0.0.1’,8898)) # 尝试连接服务器sk.send
  • Socket编程TCP协议粘包问题
    Socket编程中,基于TCP协议的通信有时候会发生粘包问题,原因大家自行百度,已经搜到这种问题应该了解粘包产生的原因哈 TCP协议是可靠的字节流式协议,字节流可以理解为是水流,数据在网络中像水流一样传输,所以纯粹发送字符串一旦TCP底层发生粘包情况,数据表意将产生错误,比如你想发送,我今天发现一特有意思的事 这句话TCP可能给你拆成我今,天发,现一特有意,思的,事儿,只是举个简单例子哈, 我们怎么处理这种问题呢,有多种方案 一个是根据EOF拆分,这个EOF就是自定义的一个特殊符号,比如我们现在就约定\r\n为EOF,碰到这个我就认为你当前发送的消息结束掉了,这个是没问题的哈,只不过有的应用场景,比如我们聊QQ跟人的时候,想一次性打好多话给对面,然后换下行,比如下图这种情况,这种情况让根据换行截断就不合适了吧,因为毕竟是一个消息,如果你多个换行,本来一句话,根据\r\n的约定,会被切成N句话,所以这个要看应用场景 第二种就是我们约定一个数据格式,比如我们自定个规矩(逼格说的高一点叫协议),我们的协议规定,消息一定要有个包头+包体,包头(两个字节)存放消息长度,包体存放字符串的消息,好了,我们现在建立Socket通信以后把我们的数据传递给对端,对端按照我们约定的协议,先把头两个字节给摘出来,看看消息长度有多少,然后按长度向后截取,这样就是一个完整的消息包了
  • 2021最新Java面经整理 | 计算机网络篇
    2021最新Java面经整理 | 计算机网络篇 目录 一、网络层次划分 1.1 应用层 1.2 传输层 1.3 网络层 1.4 数据链路层 1.5 物理层 二、TCP/IP协议(重点) 1、概述 2、TCP报文首部格式 3、TCP协议的三次握手和四次挥手 三、UDP协议  1、UDP的概述(User Datagram Protocol,用户数据报协议) 2、使用场景 3、UDP的首部格式 四、TCP和UDP的区别 五、TCP如何保证可靠传输 1、校验和 2、确认应答与序列号 3、超时重传 4、连接管理 5、流量控制 6、拥塞控制 六、TCP的三次握手四次挥手 1、TCP报文格式 2、三次握手 3、四次挥手 4、为什么三次握手和四次挥手? 5、为什么客户端最后还要等待2MSL? 七、TCP的粘包和拆包 1、粘包、拆包表现形式 2、粘包、拆包发生原因 3、粘包、拆包解决办法 八、其他协议 1、DNS协议 2、ARP/RARP协议 3、NAT协议 4、DHCP协议 5、HTTP协议 九、HTTP 与 HTTPS 1、基本概念 2、HTTP 与 HTTPS 区别 3、HTTPS 的工作原理 十、一个完整的HTTP请求流程 1、示例一 2、示例二 3、示例三 十一、其他问题 1、HTTP长连接、短连接 2、HTTP 1.0和HTTP 1.1的主要区别是什么? 3、HTTP是不保存状态的协议
  • 海量面经来袭!阿里钉钉、ICBU、CBU、蚂蚁、全在这里了,看完要个20K没什么问题!
    前言 阿里提前批面了很多部门,除了淘系一面其他都过了,最终点了国际化中台的内推,在焦急等hr面中,分享面经,希望能帮到大家,都能拿到满意的offer~ 3.3阿里CBU一面 项目30分钟(流程+项目难点+部署) JVM类加载过程 主要类加载器有什么 双亲委派模型的好处 双亲委派模型怎么打破 什么软件/应用打破了双亲委派模型 常用设计模式介绍(代理模式、包装模式、工厂模式、适配器模式、责任链模式…) 包装模式在JDK中哪里应用了、责任链模式在哪里应用 工厂模式在Spring源码中哪里有应用 多线程在项目中的应用 定义线程池的方法 Callable和Runnable的区别 FutureTask介绍 BeanFactory和ApplicationContext区别 Bean的生命周期 Java中实现Map接口的有什么 遍历HashMap的几种方法 Java8中JVM运行时数据结构变化是什么(元空间取代了方法区) 为什么用元空间取代方法区 业界大数据新技术,比如Hadoop了解吗? Java中的包装类有什么用(Integer Long Double),为什么需要包装类 TCP的粘包?粘包怎么解决?UDP会粘包吗? TCP面向什么传输,UDP面向什么传输? RPC了解吗? 线程的声明周期? 迪杰斯特拉最短路径算法? 选择排序是稳定的吗,时间复杂度? 快排稳定吗,时间复杂度,什么时候性能最差?
  • Socket 粘包 拆包;
    为什么会粘包?举个栗子: Socket连接成功就相当于通讯管道已经建立,客户端就一直从管道中取数据,如果数据一次没有取完就会发生遗留,这些遗留的数据就会和下次的数据包一起传输过来,然后就粘包了; 再看个数据: 采用0x7e 表示,若校验码、消息头以及消息体中出现0x7e,则要进行转义处理,转义 规则定义如下: 0x7e <————> 0x7d后紧跟一个0x02; 0x7d <————> 0x7d后紧跟一个0x01。 转义处理过程 如下: 发送消息时:消息封装——>计算并填充校验码——>转义; 接收消息时:转义还原——>验证校验码——>解析消息。 示例: 发送一包内容为0x30 0x7e 0x08 0x7d 0x55的数据包,则经过封装如下: 0x7e 0x30 7d 0x02 0x08 0x7d 0x01 0x55 0x7e。 7E就是标识位,拿到数据如果首尾时7E且中间没有出现7E,则说明数据正常,如果不是这样则需要拆包; 也就是,从第一个7E开始读取数据,读到第二个7E数据结束; 1、7E8001000501833996222200130014000200DB7E 2、7E8001000501833996222200130014000200DB 3、7E7E8001000501833996222200130014000200DB7E (数据已经由byte数组转为十六进制字符串)
  • Go语言基础之网络编程
    目录一、互联网协议介绍二、互联网分层模型2.1 物理层2.2 数据链路层2.3 网络层2.4 传输层2.5 应用层三、socket编程四、socket图解五、Go语言实现TCP通信5.1 TCP协议5.2 TCP服务端5.3 TCP客户端六、TCP黏包6.1 黏包示例6.2 为什么会出现粘包6.3 解决办法七、Go语言实现UDP通信7.1 UDP协议7.2 UDP服务端7.3 UDP客户端更新、更全的《Go从入门到放弃》的更新网站,更有python、go、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11517502.html现在我们几乎每天都在使用互联网,我们前面已经学习了如何编写Go语言程序,但是如何才能让我们的程序通过网络互相通信呢?本章我们就一起来学习下Go语言中的网络编程。 关于网络编程其实是一个很庞大的领域,本文只是简单的演示了如何使用net包进行TCP和UDP通信。如需了解更详细的网络编程请自行检索和阅读专业资料。一、互联网协议介绍互联网的核心是一系列协议,总称为”互联网协议”(Internet Protocol Suite),正是这一些协议规定了电脑如何连接和组网。我们理解了这些协议,就理解了互联网的原理。由于这些协议太过庞大和复杂,没有办法在这里一概而全,只能介绍一下我们日常开发中接触较多的几个协议。二
  • 阿里钉钉、ICBU、CBU、蚂蚁、国际化中台Java后台面经
    前言 阿里提前批面了很多部门,除了淘系一面其他都过了,最终点了国际化中台的内推,在焦急等hr面中,分享面经,希望能帮到大家,都能拿到满意的offer~ 3.3阿里CBU一面 项目30分钟(流程+项目难点+部署) JVM类加载过程 主要类加载器有什么 双亲委派模型的好处 双亲委派模型怎么打破 什么软件/应用打破了双亲委派模型 常用设计模式介绍(代理模式、包装模式、工厂模式、适配器模式、责任链模式…) 包装模式在JDK中哪里应用了、责任链模式在哪里应用 工厂模式在Spring源码中哪里有应用 多线程在项目中的应用 定义线程池的方法 Callable和Runnable的区别 FutureTask介绍 BeanFactory和ApplicationContext区别 Bean的生命周期 Java中实现Map接口的有什么 遍历HashMap的几种方法 Java8中JVM运行时数据结构变化是什么(元空间取代了方法区) 为什么用元空间取代方法区 业界大数据新技术,比如Hadoop了解吗? Java中的包装类有什么用(Integer Long Double),为什么需要包装类 TCP的粘包?粘包怎么解决?UDP会粘包吗? TCP面向什么传输,UDP面向什么传输? RPC了解吗? 线程的声明周期? 迪杰斯特拉最短路径算法? 选择排序是稳定的吗,时间复杂度? 快排稳定吗,时间复杂度,什么时候性能最差?
  • socket粘包的处理方法示例
    sever import struct # 把有限长度的数字变成4个字节 import subprocess # 引入子进程模块 import socket sever = socket.socket() sever.bind((‘192.168.3.7’, 9000)) sever.listen(5) while 1: print(‘sever working 开始等待链接’) conn, addr = sever.accept() while 1: try: data = conn.recv(1024) res = subprocess.Popen(data.decode(‘utf-8’), # 创建子进程对象 第一个参数是操作系统命令string类型 shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() # 操作系统命令标准错误 返回的字符串 out = res.stdout.read() # 操作系统命令标准输出 返回的字符串 if err: conn.send(struct.pack(‘i’, len(err))) conn.send(err) break else: conn.send(struct.pack(‘i’, len(out))) conn
  • 一文读懂TCP协议UDP协议的特点(区别)
    最近复习到网络,Linux的复习也将接近尾声。在这我将改正自己做事龙头蛇尾的一贯作风。在网络编程这个模块中也会认真做好笔记。 网络模块是一个面试必问的模块,这一块内容较多,但大多都是知识点,代码量就一个TCP和UDP的编程流程。 从这篇文章开始,我会将网络编程的知识点一一进行总结。 一下内容参考《计算机网络》(谢希仁)第五版。 目录 1.TCP协议的特点 2.UDP协议的特点 1.TCP协议的特点 tcp协议的主要特点如下: TCP是面向连接的的运输层协议。 这就是说,应用程序在使用TCP协议之前,必须先建立TCP连接。在传送完数据之后,必须对已建立的TCP连接进行释放。这就是说,应用程序之间的的通信好像在“打电话”;通话前先要拨号,打电话建立连接,通话结束后要挂断电话释放连接。 TCP连接是点对点的。 每一条TCP连接只能有两个端点。但是一般在服务器上我们有不止一个客户端的请求,这时候就要建立多条TCP连接。 TCP提供可靠交付的服务。 也就是说,通过TCP连接传送的数据,无差错、不丢失、不重复并且按序到达。 TCP提供全双工通信 TCP允许通信双方的应用程序在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。应用程序在把数据发送给TCP的缓存后,就可以继续做自己的事情,而TCP在合适的时候会将缓存中的数据发送出去。在接收时
  • 【6】Java基础51-60
    目录 知识点51:说一下 tcp 粘包是怎么产生的? 知识点52:OSI 的七层模型都有哪些? 知识点53:get 和 post 请求有哪些区别? 知识点54:如何实现跨域? 方式一:图片ping或script标签跨域 方式二:JSONP跨域 方式三:CORS 方式四:window.name+iframe 方式五:window.postMessage() 方式六:修改document.domain跨子域 方式七:WebSocket 方式八:代理 知识点55:说一下 JSONP 实现原理? 知识点56:jsp 和 servlet 有什么区别? 知识点57:jsp 有哪些内置对象?作用分别是什么? 知识点58:说一下 jsp 的 4 种作用域? 知识点59:session 和 cookie 有什么区别? 知识点60:说一下 session 的工作原理? 知识点51:说一下 tcp 粘包是怎么产生的? ①. 发送方产生粘包: 采用TCP协议传输数据的客户端与服务器经常是保持一个长连接的状态(一次连接发一次数据不存在粘包),双方在连接不断开的情况下,可以一直传输数据;但当发送的数据包过于的小时,那么TCP协议默认的会启用Nagle算法,将这些较小的数据包进行合并发送(缓冲区数据发送是一个堆压的过程);这个合并过程就是在发送缓冲区中进行的,也就是说数据发送出来它已经是粘包的状态了。
  • boost项目复盘(二)
    预处理1.首先是预处理模块,这里输入的是boost离线版本的html文件,需要从boost官网下载对应版本的离线包,我们这里使用的是boost1.53版本,从官网下载好以后从压缩包里可以找到一个doc目录,里面的html目录文件就是我么要使用的“原始数据”。光拿到html还不够,对于网页的html文件,会具有一下特点:这里拿boost官网首页源代码为例,可以明显看到有许多诸如<div>,<head>,<title>这样的结构,这种结构在前端的语言当中叫做标签。用于页面的渲染,而对于我们实现的功能而言,标签与正文是无关的,所以第一个要点就开始了——如何去标签。经过观察不难发现,标签的特点都是框在一对尖括号当中的,所以我们可以反向思考,只要是由 > 开始到 < 结束的就是正文部分。因此,对于此处我们是这样操作的:创建一个bool变量作为标记,判断当前是否为正文,以<为进入标签的标记,一旦进入<则接下来的内容就不会写入,而一离开>则开始写入最终结果,也就是代码中的content。但这里并不非常严谨,只是简单粗暴的把标签去掉,因为正文中出现的不一定就全是我们需要的。而此时预处理的过程还没有结束,我们现在得到的去掉标签的文件还是一团由标题,正文以及url组成的乱麻(此处涉及粘包问题,只要是涉及字节流的问题都会联系到粘包问题),想要作为下一个模块的输入部分还需要将他们按一定格式处理
  • Python入门(目录全览)-------已更新到第八篇完结
    文章目录 Python入门(目录全览)==已更新到第八篇完结==第一篇 计算机基础第二篇 Python解释器和集成环境第三篇 Python基础第四篇 Python进阶第五篇 文件处理第六篇 函数基础第七篇 函数进阶第八篇 模块基础第九篇 Python常用模块第十篇 面向对象基础第十一篇 面向对象进阶第十二篇 面向对象高阶第十三篇 网络编程第十四篇 并发编程第十五篇 MySQL数据库 Python入门(目录全览)已更新到第八篇完结 第一篇 计算机基础 002 计算机基础之编程 003 计算机组成原理 004 计算机操作系统 005 编程语言分类 006 网络的瓶颈效应 007 计算机基础小结 第二篇 Python解释器和集成环境 008 Python和Python解释器 009 Python解释器安装 010 Anaconada安装 011 Python解释器镜像源修改 012 执行Python程序的两种方式 013 Python的IDE之Pycharm的使用 014 Python的IDE之Jupyter的使用 015 pip的使用 第三篇 Python基础 017 变量 018 常量 019 Python变量内存管理 020 变量的三个特征 021 花式赋值 022 注释 023 数据类型基础 024 数字类型 025 字符串类型 026 列表类型 027 字典类型 028
  • HTTP、UDP以及TCP协议,以及三次握手和四次挥手
    协议解析:HTTP,TCP,UDP,IP 应用层 HTTP协议: 超文本传输协议,最早只用来传输HTML 是一个应用层协议,是应用程序组织数据的格式。组织完毕传输数据时在传输层使用TCP协议 HTTP服务器/客户端就是TCP服务器/客户端,只是在上层使用了HTTP组织以及解析数据 HTTP协议是一个字符串明文协议,将数据组织成特定形式的字符串进行传输 书:《图解HTTP协议》 协议实现: 协议即数据格式的约定,协议实现即查看协议如何组织数据格式 1 首行:数据的第一行 请求首行:分为三部分,包含三个要素,要素之间以空格间隔,最终首行以隐藏的\r\n结尾 三个要素: 请求方法:决定本次请求目的 GET:主要用于获取请求一个页面信息,返回实体资源;也可以提交数据,该数据保存在URL中(GET没有正文),长度有限制并且不安全(比如搜索时,提交搜索的信息,返回搜索结果页面) POST:向服务器提交表单数据(比如登录提交用户名密码);提交的数据在正文中,长度没有限制,安全度较高 HEAD:与GET相似,只不过返回的响应没有具体内容只返回报头 URL:统一资源定位符,即网址,定位网络中某台主机上的某个资源 组成信息:http://username:password@www.frish.com:80/path?key=val&key=val#ch 协议方案名:http,https,ftp
  • 阿里高并发Netty开源框架,撸完人已猝!!!
    JDK从1.4版本引入 NIO 的类库,但是其设计有点反人类,使用较为麻烦,需要熟练掌握Selector、 ServerSocketChannel、 SocketChannel、 ByteBuffer等很多类库的使用。 在用NIO类库开发网络程序时还面临大量复杂问题需要解决,例如客户端断线重连、 网络闪断、心跳处理、半包读写、 网络拥塞和异常流的处理等等。Netty作为现在最流行的网络通信框架,对 JDK 自带的 NIO 的类库进行了良好的封装,解决了上述NIO问题。且Netty拥有高性能、 吞吐量更高、延迟更低、减少资源消耗,最小化不必要的内存复制等优点。大家耳熟能详的一些中间件底层都大量的使用Netty,比如:Dubbo、Zookeeper、RocketMQ、Gateway、Spark等等。 Netty也是现在一线互联网公司面试必问的技术,但是很多同学因为工作缘故对Netty接触不多,或者只是简单用用,对Netty底层原理知之甚少,下面是我搜集的一些关于Netty的一些面试题,看看你能回答上几个? P7面试题 1、BIO、NIO和AIO模型的区别 2、同步与异步、阻塞与非阻塞的区别 3、select、poll、epoll的机制及其区别 4、Netty底层操作与Java NIO操作对应关系如何 5、Netty的线程模型是怎样的,与Redis线程模型有区别吗 6