我已经编写了一个代码来实现SSL套接字(服务器/客户端)和证书身份验证等正在正确完成。当代码尝试读取客户端传递给服务器的字符串时代码停止。请帮忙。
这是我用来创建SSLServerSocket的文件:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Random;
import javax.net.ssl.*;
public class Server {
private String ksname;
private char kspass[], ctpass[];
private int port;
private InetAddress ip;
public Server(){
ksname = null;
kspass = new char[200];
ctpass = new char[200];
kspass = null;ctpass = null;
port = 10000 + (new Random()).nextInt(10000);
try {
ip = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Server(String cname, String cpass, String pass, int p, String host){
ksname = cname;
kspass = new char[200];
kspass = cpass.toCharArray();
ctpass = new char[200];
ctpass = pass.toCharArray();
port = p;
try {
ip = InetAddress.getByName(host);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public SSLServerSocket getServer(){
SSLServerSocket s = null;
try {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(ksname), kspass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, ctpass);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
s = (SSLServerSocket) ssf.createServerSocket(port,0,ip);
System.out.println("Server created on port " + port +"\n");
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
}
这是服务器的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Map;
import java.util.Random;
import javax.net.ssl.*;
public class MServer {
private SSLSocket c = null;
private BufferedReader r = null;
private BufferedWriter w = null;
private int port = 10579;
private void execute(){
Server server = new Server("ppp.jks", "user", "pass", port, "127.0.0.1");
SSLServerSocket s = server.getServer();
printServerSocketInfo(s);
try {
c = (SSLSocket) s.accept();
printSocketInfo(c);
r = new BufferedReader(new InputStreamReader(c.getInputStream()));
w = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));
System.out.println("in m");
System.out.flush();
String str = null;
str = r.readLine();
System.out.println(str);
if(str.equals("hi")){
w.write("Connection OK");
System.out.println("Connection OK2");
}
while((str = r.readLine()) != null){
if(str.equals("done")){
break;
}
resolve(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void resolve(String str){
//does something
}
private void printMessage(int returnValue, int correctReturnValue, String printFor){
//something
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: "+s.getClass());
System.out.println(" Remote address = "
+s.getInetAddress().toString());
System.out.println(" Remote port = "+s.getPort());
System.out.println(" Local socket address = "
+s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+s.getLocalAddress().toString());
System.out.println(" Local port = "+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = "+ss.getCipherSuite());
System.out.println(" Protocol = "+ss.getProtocol());
}
private static void printServerSocketInfo(SSLServerSocket s) {
System.out.println("Server socket class: "+s.getClass());
System.out.println(" Socket address = "
+s.getInetAddress().toString());
System.out.println(" Socket port = "
+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
System.out.println(" Want client authentication = "
+s.getWantClientAuth());
System.out.println(" Use client mode = "
+s.getUseClientMode());
}
public static void main(String args[]){
MServer m = new MServer();
m.execute();
}
}
和客户:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class ReqResServer {
private BufferedWriter w1 = null;
private BufferedWriter w2 = null;
private BufferedReader r1 = null;
private BufferedReader r2 = null;
private SSLSocket c1 = null;
private SSLSocket c2 = null;
private int port = 24910;
public void doClient(){
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
System.out.println("f created");
try {
c1 = (SSLSocket) f.createSocket("127.0.0.1", 10579);
System.out.println("c1 created");
printSocketInfo(c1);
c1.startHandshake();
w1 = new BufferedWriter(new OutputStreamWriter(c1.getOutputStream()));
r1 = new BufferedReader(new InputStreamReader(c1.getInputStream()));
w1.write("hi");
System.out.println("hi");
String str = r1.readLine();
System.out.println("before if " + str);
if(str.equals("Connection OK")){
//do something
System.out.println(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: "+s.getClass());
System.out.println(" Remote address = "
+s.getInetAddress().toString());
System.out.println(" Remote port = "+s.getPort());
System.out.println(" Local socket address = "
+s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+s.getLocalAddress().toString());
System.out.println(" Local port = "+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = "+ss.getCipherSuite());
System.out.println(" Protocol = "+ss.getProtocol());
}
public static void main(String args[]){
ReqResServer req1 = new ReqResServer();
req1.doClient();
}
}
这是输出: 服务器控制台:
Server created on port 10579
Server socket class: class sun.security.ssl.SSLServerSocketImpl
Socket address = /127.0.0.1
Socket port = 10579
Need client authentication = false
Want client authentication = false
Use client mode = false
Socket class: class sun.security.ssl.SSLSocketImpl
Remote address = /127.0.0.1
Remote port = 51297
Local socket address = /127.0.0.1:10579
Local address = /127.0.0.1
Local port = 10579
Need client authentication = false
Cipher suite = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Protocol = TLSv1.2
in m
null
即。它不打印hi
并继续它应该。
和客户端控制台:
f created
c1 created
Socket class: class sun.security.ssl.SSLSocketImpl
Remote address = /127.0.0.1
Remote port = 10579
Local socket address = /127.0.0.1:51297
Local address = /127.0.0.1
Local port = 51297
Need client authentication = false
Cipher suite = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Protocol = TLSv1.2
hi
这显然意味着正在执行w1.write("hi")
。
那么,为什么代码不会继续?我花了3个多小时在这上面,我没有到达任何地方。它有点详尽,但任何帮助将不胜感激。
答案 0 :(得分:1)
首先,您使用的是BufferedWriter,这意味着您写入的任何内容都可能无法立即刷新。然后你只写hi
,即你写这两个字符但不是行尾。但是在执行readLine
时你等待行结束。此函数需要一个完整的行,其中包括行结束。它只会在收到行结束或套接字关闭后返回。