основная проблема программирования сокетов java

Я прочитал много вопросов/ответов по программированию сокетов Java, но ни один из них не относится к моей текущей проблеме.

Я написал базовую программу сокетов java ssl, единственной целью которой (на данный момент) является установление ssl-соединения между клиентом и сервером и отправка клиентом одного подписанного сообщения. Если сообщение проверяется сервером, он должен ответить соответственно (true!) или иначе (false!).

Я застреваю после этапа рукопожатия, когда клиент отправляет «сообщение» на сервер и ждет ответа сервера. Тем временем сервер не обрабатывает сообщение, отправленное клиентом, поэтому он не может ответить, и я жду, когда кто-либо из них закончит с этим.

Можете ли вы сказать мне, где я сделал ошибку?

Чтобы не отображать огромное количество нерелевантного кода, я не включил ни объект значения SignedMessage, ни класс Utils. Методы, используемые в классе utils, предназначены для сериализации и десериализации, а также для преобразования строки в массив байтов. Я знаю, что мог бы использовать String.getBytes(), но мне нравилось выполнять преобразование вручную. Все перечисленные методы проверены и работают нормально.

код метода запуска ServerThread

public void run() {
    try {
        InputStream in = sslSocket.getInputStream();
        OutputStream out = sslSocket.getOutputStream();

        //if I write some output here the program works well, but this is not what I want to do 
        //out.write('!');

        //BASE64 DECODING
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        int ch;
        while((ch = in.read()) != -1)
            bos.write(ch);

        ByteArrayOutputStream decoded = new ByteArrayOutputStream();
        Base64Encoder encoder = new Base64Encoder();
        encoder.decode(bos.toByteArray(), 0, bos.toByteArray().length, decoded);

        //reconstructing the the SignedMessage object

        SignedMessage signedMessage = (SignedMessage) Utils.deserializeObject(decoded.toByteArray());

        if(checkSignature(signedMessage.getMessage().getBytes("UTF-8"), signedMessage.getSignature(), signedMessage.getCertificate())){
            System.out.println(String.valueOf(signedMessage.getMessage()));

            //this i where I would like to write out the answer, but the code never get executed
            out.write(Utils.toByteArray("TRUE!"));
            out.flush();
        }
        else {
            out.write(Utils.toByteArray("false!"));
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            sslSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    System.out.println("Thread closed");
}

Это код клиента, который осуществляет связь

static void doProtocol(SSLSocket sslSocket) throws IOException, UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException  {

    OutputStream     out = sslSocket.getOutputStream();
    InputStream      in = sslSocket.getInputStream();

    byte[] signature = generateSignature(Utils.toByteArray(Message), (PrivateKey) clientStore.getKey(Utils.CLIENT_NAME, Utils.CLIENT_PASSWORD), 
            clientStore.getCertificate(Utils.CLIENT_NAME).getPublicKey().getAlgorithm());

    //BASE64 ENCODING
    byte[] object = Utils.serializeObject(new SignedMessage(Message, signature, clientStore.getCertificate(Utils.CLIENT_NAME)));

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Base64Encoder encoder = new Base64Encoder();
    encoder.encode(object, 0, object.length, bos);

    out.write(bos.toByteArray());
    out.flush();

    int ch;
    while((ch = in.read()) != '!')
        bos.write(ch);

    System.out.println("Sesion closed");
}

person proton    schedule 26.05.2011    source источник
comment
похоже, что поток вашего сервера запускается, пытается читать из сокета, а затем завершается? таким образом, обрабатывается только рукопожатие?   -  person Karl-Bjørnar Øie    schedule 26.05.2011
comment
Дело в том, что я хочу, чтобы поток сервера проверял, является ли сообщение, отправленное клиентом, действительным или нет, и давал ответ на основе этой информации. Когда я отлаживаю код, сервер никогда не доходит до того момента, когда он анализирует сообщение клиента, потому что клиент застревает, пытаясь прочитать ответ сервера.   -  person proton    schedule 26.05.2011
comment
Вы не будете читать EOS, пока пир не закроет соединение. Но я не понимаю, зачем все ByteArrayOutputStreams, кодировщики/декодеры и т. д. Вы можете сделать все это с ObjectInput/OutputStreams, обернутыми непосредственно вокруг потоков сокетов, и сэкономить себе много времени и места.   -  person user207421    schedule 26.05.2011


Ответы (1)


это

while((ch = in.read()) != -1)
        bos.write(ch);

блоки навсегда. Это фактически разблокируется, когда поток (соединение) закрыт. Так что вам решать определить конец сообщения. Я имею в виду, что конец сообщения не означает конец потока. Итак, после того, как вы получили свое сообщение, вы будете бесконечно ждать чего-то еще от канала. Как вы на самом деле сделали здесь

while((ch = in.read()) != '!')
    bos.write(ch);
person Oleg    schedule 26.05.2011
comment
Большое спасибо за комментарий. Я, должно быть, пропустил это в спешке. - person proton; 26.05.2011