有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java readLine()无法正常工作

我已经编写了一段代码来实现SSLsocket(服务器/客户机)和证书身份验证等。这些工作正在正确完成。当代码试图读取客户端传递给服务器的字符串时,代码停止。请帮忙

这是我用来创建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个多小时在这上面了,我什么也没有得到。这是一个有点详尽,但任何帮助将不胜感激


共 (1) 个答案

  1. # 1 楼答案

    首先,您使用的是BufferedWriter,这意味着您向其写入的任何内容都可能不会立即刷新。然后只写hi,即写这两个字符,但不写行尾。但是在执行readLine时,您需要等待一个行结束。此函数需要一个完整的行,其中包括行尾。它只会在收到线路端或套接字关闭后返回