yeg
2026-08-25 6ba67935468ff5129f9341da0cf884af2756c0e5
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.ruoyi.device.bts;
 
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
 
final class ScriptedBtsTcpSimulator implements AutoCloseable
{
    private static final byte[] FRAME_END = "#\r\n".getBytes(StandardCharsets.UTF_8);
 
    private final ServerSocket serverSocket;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final BlockingQueue<String> responses = new LinkedBlockingQueue<>();
    private final List<String> requests = new CopyOnWriteArrayList<>();
 
    ScriptedBtsTcpSimulator() throws IOException
    {
        serverSocket = new ServerSocket(0);
        executor.submit(this::serve);
    }
 
    int port()
    {
        return serverSocket.getLocalPort();
    }
 
    void enqueue(String response)
    {
        responses.add(response);
    }
 
    List<String> requests()
    {
        return List.copyOf(requests);
    }
 
    private void serve()
    {
        try (Socket socket = serverSocket.accept())
        {
            while (!socket.isClosed())
            {
                String request = readFrame(socket.getInputStream());
                requests.add(request);
                String response = responses.poll(5, TimeUnit.SECONDS);
                if (response == null) throw new IOException("No scripted BTS response available");
                socket.getOutputStream().write(response.getBytes(StandardCharsets.UTF_8));
                socket.getOutputStream().write(FRAME_END);
                socket.getOutputStream().flush();
            }
        }
        catch (Exception ignored)
        {
        }
    }
 
    private String readFrame(InputStream input) throws IOException
    {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int matched = 0;
        while (true)
        {
            int value = input.read();
            if (value < 0) throw new IOException("Client disconnected");
            if ((byte) value == FRAME_END[matched])
            {
                matched++;
                if (matched == FRAME_END.length) return buffer.toString(StandardCharsets.UTF_8);
                continue;
            }
            if (matched > 0)
            {
                buffer.write(FRAME_END, 0, matched);
                matched = 0;
            }
            buffer.write(value);
        }
    }
 
    @Override
    public void close() throws Exception
    {
        serverSocket.close();
        executor.shutdownNow();
        executor.awaitTermination(2, TimeUnit.SECONDS);
    }
}