Несколько мыслей:
len = Integer.parseInt(fromPU.trim());
Вы должны проверить данный размер по максимуму, который имеет некоторый смысл. Ваш сервер вряд ли отправит сообщение размером в два гигабайта клиенту. (Возможно, так и будет, но может быть и лучший дизайн. :) Обычно вы не хотите выделять столько памяти, сколько удаленный клиент просит выделить. Это рецепт для простых удаленных атак на отказ в обслуживании.
BufferedReader br = new BufferedReader(new InputStreamReader(ins));
/* ... */
bytes =ins.read(buffer);
Может быть ваш BufferedReader
засосал слишком много данных? (Сервер ждет для Ok
, прежде чем продолжить?) Вы уверены, что вам разрешено читать из базового объекта InputStreamReader
после присоединения объекта BufferedReader
?
Обратите внимание, что TCP может свободно доставлять ваши данные в виде десятибайтовых блоков в течение следующих двух недель :) - потому что инкапсуляция, различное оборудование и т. Д. Очень затрудняет определение размера пакетов, которые в конечном итоге будут использоваться между два пира, большинство приложений, которые ищут определенный объем данных, вместо этого будут заполнять свои буферы, используя код, похожий на этот (украдено из Advanced Programming в Unix Environment, отличная книга; жаль, что код на C и ваш код на Java, но принцип тот же):
ssize_t /* Read "n" bytes from a descriptor */
readn(int fd, void *ptr, size_t n)
{
size_t nleft;
ssize_t nread;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount read so far */
} else if (nread == 0) {
break; /* EOF */
}
nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
Смысл в том, что для заполнения буфера может потребоваться один, десять или сто вызовов read()
, а ваш код должен быть устойчивым к небольшим изменениям в сетевых возможностях.