В сокет отправляется не полная строка

126
08 июля 2019, 01:30

Есть клиент на java, который отправляет длинный json на сервер, который написан на python. Если длина json'а не очень большая, то все нормально отправляется. Если же строка большая, то доходит не вся. Обрывается где-то на 1500 символах (не точно).

Клиент:

    private static void connect(String ip, int port) throws IOException {
        long sessionId = new Random().nextLong();
        queue.add(sessionId);
        while (!(queue.size() <= 0 || queue.get(0).equals(sessionId)))
            try { Thread.sleep(200); } catch (InterruptedException ignored) { }
        socket = new Socket(ip, port);
    }
    static String sendJsonForResult(String json) throws IOException {
        return sendJsonForResult(json, TIMEOUT);
    }
    static String sendJsonForResult(String json, int timeout) throws IOException {
        try {
            connect(ip, port);
            if (socket == null) throw new IOException("Socket is null");
            socket.setSoTimeout(timeout);
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            dos.write(json.getBytes("UTF-8"));
            dos.flush();
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String response = in.readLine();
            if (response == null || response.equals(""))
                throw new IOException(String.format("Incorrect response (%s)", response));
            Log.d("CLIENT", "Answer:\n\t" + response);
            return response;
        } finally {
            disconnect();
        }
    }
    private static void disconnect() {
        try {
            socket.close();
        } catch (Exception ignored) { }
        if (queue.size() > 0) queue.remove(0);
    }

Сервер:

try:
    tcp_socket.bind((host, port))
except socket.error as e:
    print('[SERVER] ERROR: ' + str(e))
tcp_socket.listen(10)
while true:
    conn, addr = tpc_socket.accept()
    try:
        data = conn.recv(1048576)
        data = data.decode('utf-8')
        if data != '':
            print('[SERVER] Received data from ' + addr[0] + ':\n\t' + data)

Как мне решить эту проблему?

Answer 1

Проблема решена. Спасибо @nick_n_a и @gil9red за наводку. Сначала в питоне я сделал следующее, как в комментариях и рекомендовали:

while true:
    conn, addr = tpc_socket.accept()
    try:
        databytes = bytesarray()
        while True:
             databuff = conn.recv(4096)
             if not databytes:
                 break
             databytes += databuff
        data = databytes.decode('utf-8')
        if data != '':
            print('[SERVER] Received data from ' + addr[0] + ':\n\t' + data)

Но появилась следующая проблема - запрос не отправлялся, пока сокет на клиенте не закроется. Я пытался закрыть OutputStream, но закрывался и сокет вместе с ним, а мне надо было еще и прочитать ответ.

Решение оказалось следующим: вместо OutPutStream.close() использовать Socket.shutdownOutput().

Вот код клиента:

private static void connect(String ip, int port) throws IOException {
    long sessionId = new Random().nextLong();
    queue.add(sessionId);
    while (!(queue.size() <= 0 || queue.get(0).equals(sessionId)))
        try { Thread.sleep(200); } catch (InterruptedException ignored) { }
    socket = new Socket(ip, port);
}
static String sendJsonForResult(String json) throws IOException {
    return sendJsonForResult(json, TIMEOUT);
}
static String sendJsonForResult(String json, int timeout) throws IOException {
    try {
        connect(ip, port);
        if (socket == null) throw new IOException("Socket is null");
        socket.setSoTimeout(timeout);
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        dos.write(json.getBytes("UTF-8"));
        dos.flush();
        socket.shutdownOutput();
        String response = in.readLine();
        if (response == null || response.equals(""))
            throw new IOException(String.format("Incorrect response (%s)", response));
        Log.d("CLIENT", "Answer:\n\t" + response);
        return response;
    } finally {
        disconnect();
    }
}
private static void disconnect() {
    try {
        socket.close();
    } catch (Exception ignored) { }
    if (queue.size() > 0) queue.remove(0);
}
READ ALSO
Разбиение строки на группы в регулярных выражениях

Разбиение строки на группы в регулярных выражениях

Хочу проверить строку на наличие хаотически выставленных букв разных регистровДля примера строка на входе:

144
Можно ли писать на Java для iOS?

Можно ли писать на Java для iOS?

До меня дошли страшные слухи, что на iOS нет JVMБолее того, до меня дошли страшные слухи, что будто бы фирма Эппл не разрешает ставить JVM на iOS

172
Как создать корзину в Java? [закрыт]

Как создать корзину в Java? [закрыт]

Нужно создать интернет-магазинПользователь выбирает товары, они складываются в корзину

158
Проблема с выводом Объекта из файла

Проблема с выводом Объекта из файла

Создаю небольшое приложение, при нажатии на кнопку регистрации создается объект

146