基本的Java套接字编程问题 [英] basic java socket programming problem

查看:76
本文介绍了基本的Java套接字编程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多有关Java套接字编程的问题/答复,但是没有一个适用于我当前的问题.

I have read a lot of the questions/replies to java socket programming, but none of them apply to my current issue.

我已经编写了一个基本的Java ssl套接字程序,目前,其唯一目的是在客户端和服务器之间建立ssl连接,并由客户端发送一条已签名的消息.如果邮件已由服务器验证,则应相应地以(true!)或其他方式以(false!)进行回复.

I have written a basic java ssl socket program, whose sole purpose (for the moment) is to establish an ssl connection between the client and server and send one signed message by the client. If the message gets verified by the server, it should reply accordingly with (true!) or otherwise with (false!).

当客户端向服务器发送消息"并等待服务器响应时,握手后卡住了.同时,服务器不会处理客户端发送的消息,因此它无法响应,我在那里等待他们中的任何一个继续处理.

I get stuck after the handshake pase, when the client sends a "message" to the server and waits for the server to respond. Meanwhile the server does not process the message the client sent, so it can't respond and there I am waiting for either of them go it over with.

你能告诉我我哪里做错了吗?

Can you tell me where I made a mistake?

为了不显示大量不相关的代码,我没有包含值对象SignedMessage或Utils类. utils类使用的方法用于序列化和反序列化,以及将String转换为字节数组.我知道我可以使用String.getBytes(),但是我喜欢手工完成转换.所有提到的方法都已经过测试并且可以正常工作.

In order not to display huge amounts of not relevant code I have not included the value object SignedMessage nor the Utils class. The methods used from the utils class are for serialization and deserialization and for converting a String to an array of bytes. I know that I could have used String.getBytes(), but I liked to have the conversion done by hand. All mentioned methods have been tested and work fine.

ServerThread运行方法代码

the ServerThread run method code

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");
}

这是进行通信的客户代码

This is the Client code which does the communication

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");
}

推荐答案

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

永远封锁.当流(连接)关闭时,这实际上将解除阻塞. 因此,由您来确定消息的结尾. 我的意思是消息的结束并不意味着流的结束.因此,在收到您的消息后,您将无限期地等待来自渠道的其他消息. 就像您在这里所做的

blocks forever. This actually will unblock when the stream (connection) is closed. So it's up to you to identify end of message. I mean that end of message does not mean end of stream. So After you've received your message you will infinitely wait for smth else from the channel. As you actually did here

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

这篇关于基本的Java套接字编程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆