Есть клиент на 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)
Как мне решить эту проблему?
Проблема решена. Спасибо @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);
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости