【发布时间】:2011-09-02 14:00:02
【问题描述】:
我已经阅读了很多关于 java 套接字编程的问题/回复,但没有一个适用于我当前的问题。
我编写了一个基本的 java ssl 套接字程序,其唯一目的(目前)是在客户端和服务器之间建立一个 ssl 连接,并由客户端发送一个签名消息。如果消息被服务器验证,它应该相应地回复 (true!) 或回复 (false!)。
当客户端向服务器发送“消息”并等待服务器响应时,我在握手之后卡住了。同时,服务器不处理客户端发送的消息,因此无法响应,我正在等待他们中的任何一个处理。
你能告诉我哪里出错了吗?
为了不显示大量不相关的代码,我没有包含值对象 SignedMessage 和 Utils 类。 utils 类中使用的方法用于序列化和反序列化以及将 String 转换为字节数组。我知道我可以使用 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");
}
【问题讨论】:
-
看起来您的服务器线程正在运行,尝试从套接字读取,然后结束?因此只处理握手?
-
重点是我希望服务器线程检查客户端发送的消息是否有效,并根据该信息给出答案。当我调试代码时,服务器永远不会分析客户端消息,因为客户端在尝试读取服务器回复时卡住了。
-
在对等方关闭连接之前,您不会读取 EOS。但我不明白为什么要使用所有 ByteArrayOutputStreams、编码器/解码器等。您可以使用直接包裹在套接字流周围的 ObjectInput/OutputStreams 来完成所有这些工作,并为自己节省大量时间和空间。
标签: java sockets inputstream outputstream