【问题标题】:A client request a public from server客户端向服务器请求公共
【发布时间】:2012-04-26 06:49:10
【问题描述】:

//这是请求服务器向客户端发送公钥的代码

package gameserver;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;
import java.net.Socket;
import java.io.*;
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.*;

public class GameClient  extends JFrame implements ActionListener {

    private JButton b1 = new JButton("press");

    public GameClient () {
       GridLayout layout = new GridLayout(3, 0, 0, 0);
       setLayout(layout);
       setSize(320,150);

       add(b1);
       b1.addActionListener(this);

    }

    public static void main(String args[]) {
      java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                 GameClient frame = new GameClient();
                 frame.setVisible(true);
            }
      });
    }  

   public void actionPerformed(ActionEvent ae) {
       if (ae.getSource() == b1) {
            Socket socket = null;
            ObjectInputStream in = null;
            ObjectOutputStream out = null;

            Scanner console = new Scanner(System.in);

            try {
                socket = new Socket("127.0.0.1", 12346);
                in = new ObjectInputStream(socket.getInputStream());
                out = new ObjectOutputStream(socket.getOutputStream());
                Object result;
                result = in.readObject();

                System.out.println(result);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    } 
                    if (out != null) {
                        out.close();
                    }
                    if (socket != null) {
                        socket.close();
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }           
       }

   } 
}

//服务端代码,客户端连接时发送公钥给客户端

package gameserver;

import java.io.*;
import java.net.*;
import java.security.*; 
import javax.crypto.*; 

public class GameServer {
    public static void main(String arg[]) {
        try {
            ServerSocket ss = new ServerSocket(12346);

                        while(true) {
            Socket s = ss.accept();
            ClientHandler ch = new ClientHandler(s);
                        ch.start();

                        }
        }
        catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

class ClientHandler extends Thread  {

    Socket socket;
    KeyPair keyPair = null;

    public ClientHandler(Socket socket)  {
        this.socket = socket;

    }

    public KeyPair genKeyPair () {

        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 
            keyGen.initialize(1024); 
            keyPair = keyGen.generateKeyPair(); 
            //PrivateKey privateKey = keyPair.getPrivate();
            //PublicKey publicKey = keyPair.getPublic();

        } catch (NoSuchAlgorithmException e) {
            System.out.println(e.getMessage());
        }   
        return keyPair;
    }

    public void run() {
        try {             

            ObjectInputStream Ois = new ObjectInputStream(socket.getInputStream());               
            ObjectOutputStream Oos = new ObjectOutputStream(socket.getOutputStream());

            keyPair = genKeyPair ();
            PublicKey publicKey = keyPair.getPublic();
            Oos.writeObject(publicKey);

            socket.close();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

}

问题是,当我按下按钮时,客户端似乎没有连接到服务器,并且什么也没收到,有什么想法吗?谢谢

【问题讨论】:

  • 您可能想要尝试更激烈的调试,而不是仅仅按下按钮并期望我们涉足您的所有代码。
  • 我已经更改为使用 datainputsteam 向客户端发送一个 int,它可以工作,但是 objectinputsteam 不能工作......
  • 因为ObjectInputStream被阻塞了,看我的帖子

标签: java swing sockets concurrency


【解决方案1】:

您的代码在此行被阻止:

 ObjectInputStream Ois = new ObjectInputStream(socket.getInputStream());

来自文档

创建一个从指定对象读取的 ObjectInputStream 输入流。从流中读取序列化流标头并 已验证。这个构造函数会阻塞,直到对应的 ObjectOutputStream 已写入并刷新了标头。

如果安装了安全管理器,此构造函数将检查 调用时的“enableSubclassImplementation”SerializablePermission 直接或间接由子类的构造函数 覆盖 ObjectInputStream.readFields 或 ObjectInputStream.readUnshared 方法。

修复:

改变你的

ObjectInputStream Ois = new ObjectInputStream(socket.getInputStream());               
ObjectOutputStream Oos = new ObjectOutputStream(socket.getOutputStream());

ObjectOutputStream Oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream Ois = new ObjectInputStream(socket.getInputStream());   

【讨论】:

  • 是不是每个OutputStream和InputStream都需要先定义Output再定义Input?
  • 并非所有 InputStream 都阻塞,但 ObjectInputStream 是阻塞的。
猜你喜欢
  • 2016-02-27
  • 2018-04-01
  • 1970-01-01
  • 2020-07-15
  • 2015-06-15
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多