将两台服务器合二为一? - Java套接字

时间:2015-08-06 09:22:21

标签: java sockets server

所以我一直在努力制作一个节目。该计划有点基础。我想用发送图片制作聊天程序。所以现在的问题是我现在有两个服务器和两个客户端。一个用于聊天,另一个用于图片。我想将它们组合到一个服务器上,以使代码更少,更有用,但我不知道它是否可行。否则我需要一个提示方法如何继续这个,因为现在我卡住了。所以我的服务器看起来像这样。是否可能?





服务器聊天:




 公共服务器( int port){
 this(port,null);
 }

 public Server(int port,ServerGUI sg){
 // GUI是否
 this.sg = sg;
 //端口
 this.port = port;
 //显示hh:mm:ss
 sdf = new SimpleDateFormat(“HH:mm:ss”);
 // ClientList列表
 al = new ArrayList< ClientThread>();
 }

 public void start(){
 keepGoing = true;
 / *创建套接字服务器并等待连接请求* /
试试
 {
 //服务器使用的套接字
 ServerSocket serverSocket = new ServerSocket(port);

 //无限循环等待连接
而(keepGoing)
 {
 //格式化消息说我们正在等待
 display(“服务器等待端口上的客户端”+端口+“。”);

套接字socket = serverSocket.accept(); //接受连接
 //如果我被要求停止
如果(keepGoing!)
打破;
 ClientThread t = new ClientThread(socket); //制作一个线程
 al.add(T); //将它保存在ArrayList
 t.start();
 }
 //我被要求停止
试试{
 serverSocket.close();
 for(int i = 0; i< al.size(); ++ i){
 ClientThread tc = al.get(i);
试试{
 tc.sInput.close();
 tc.sOutput.close();
 tc.socket.close();
 }
 catch(IOException ioE){
 //我做的不多
 }
 }
 }
 catch(例外e){
 display(“关闭服务器和客户端的例外:”+ e);
 }
 }
 //事情变坏
 catch(IOException e){
 String msg = sdf.format(new Date())+“新ServerSocket上的异常:”+ e +“\ n”;
显示器(MSG);
 }
 }

类ClientThread扩展线程{
 //套接字在哪里听/说
套接字插座;
 ObjectInputStream sInput;
 ObjectOutputStream sOutput;
 //我唯一的id(更容易断开连接)
 int id;
 //客户的用户名
 String username;
 //将收到的唯一消息类型
消息cm;
 //我连接的日期
字符串日期;

 // Constructore
 ClientThread(套接字套接字){
 //一个唯一的id
 id = ++ uniqueId;
 this.socket = socket;
 / *创建数据流* /
 System.out.println(“线程试图创建对象输入/输出流”);
尝试
 {
 //首先创建输出
 sOutput = new ObjectOutputStream(socket.getOutputStream());
 sInput = new ObjectInputStream(socket.getInputStream());
 //读取用户名
 username =(String)sInput.readObject();
 display(username +“just connected。”);
 }
 catch(IOException e){
 display(“异常创建新的输入/输出流:”+ e);
返回;
 }
 //必须捕获ClassNotFoundException
 //但我读了一个字符串,我相信它会起作用
 catch(ClassNotFoundException e){
 }
 date = new Date()。toString()+“\ n”;
 }
  




图片服务器




 公共类GreetingServer {

 public final static int SOCKET_PORT = 13267; //你可以改变这个
 public final static String FILE_TO_SEND =“C:/Users/Barry/Desktop/Duck.jpg”; //你可以改变这个

 public static void main(String [] args)抛出IOException {
 FileInputStream fis = null;
 BufferedInputStream bis = null;
 OutputStream os = null;
 ServerSocket servsock = null;
 Socket sock = null;
试试{
 servsock = new ServerSocket(SOCKET_PORT);
而(真){
的System.out.println( “请稍候”);
试试{
 sock = servsock.accept();
 System.out.println(“Accepted connection:”+ sock);
 //发送文件
文件myFile =新文件(FILE_TO_SEND);
 byte [] mybytearray = new byte [(int)myFile.length()];
 fis = new FileInputStream(myFile);
 bis = new BufferedInputStream(fis);
 bis.read(mybytearray,0,mybytearray.length);
 os = sock.getOutputStream();
 System.out.println(“发送”+ FILE_TO_SEND +“(”+ mybytearray.length +“bytes)”);
 os.write(mybytearray,0,mybytearray.length);
 os.flush();
的System.out.println( “完成”。);
 }
终于{
 if(bis!= null)bis.close();
 if(os!= null)os.close();
 if(sock!= null)sock.close();
 }
 }
 }
终于{
 if(servsock!= null)servsock.close();
 }
 }
}
  



1 个答案:

答案 0 :(得分:0)

要将两种数据放在同一个套接字上,您需要在某种程度上区分这两种数据。由于您无论如何都在使用对象输入/输出流,因此使用这两个类似乎是区分的好方法。使用isAssignableFrom找出每个对象是什么。

public static class ChatText implements Serializable {

    private String text;

    /**
     * Get the value of text
     *
     * @return the value of text
     */
    public String getText() {
        return text;
    }

    /**
     * Set the value of text
     *
     * @param text new value of text
     */
    public void setText(String text) {
        this.text = text;
    }

}

...

public static class PictureData implements Serializable {

    private byte[] data;

    /**
     * Get the value of data
     *
     * @return the value of data
     */
    public byte[] getData() {
        return data;
    }

    /**
     * Set the value of data
     *
     * @param data new value of data
     */
    public void setData(byte[] data) {
        this.data = data;
    }
}

...

public static void main(String[] args) {
    try {
        // Server implemented here
        ExecutorService es = Executors.newFixedThreadPool(4);
        ServerSocket ss = new ServerSocket(1234);
        es.submit(() -> {
            while (true) {
                Socket s = ss.accept();
                es.submit(() -> {
                    ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                    while (true) {
                        Object o = ois.readObject();
                        if (PictureData.class.isAssignableFrom(o.getClass())) {
                            PictureData pd = (PictureData) o;
                            System.out.println("got picture:" + Arrays.toString(pd.getData()));
                            // Do something with picture here.
                        } else if (ChatText.class.isAssignableFrom(o.getClass())) {
                            ChatText ct = (ChatText) o;
                            System.out.println("got text:" + ct.getText());
                            // Do something with chat here.
                        }
                    }
                });
            }
        });

        // Client implemented here, just for Testing
        Socket s = new Socket("localhost", 1234);
        ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
        ChatText ct = new ChatText();
        ct.setText("first chat");
        oos.writeObject(ct);

        //In a real client, the next three lines would be in a separate 
        // class/function attached to some event handler.
        PictureData pd = new PictureData();
        pd.setData(new byte[]{1, 2, 3, 4});
        oos.writeObject(pd);

        Thread.sleep(2000); // ugly hack to make sure server doesn't close too early, for testing only
        es.shutdownNow();
        s.close();
        ss.close();

    } catch (IOException | InterruptedException ex) {
        ex.printStackTrace();
    }

}

真正的客户端会将我标记的部分放在main中,并从某个事件处理程序运行它。更像这样:

public class MyClient extends JFrame {

    MyClient(String host, int port) {
        try {
            Socket s= new Socket(host,port);
            JButton myButton = new JButton("Send Picture");
            ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
            myButton.addActionListener(e -> {
                try { 
                    // Copy of code from previous example.
                    PictureData pd = new PictureData();
                    pd.setData(new byte[]{1, 2, 3, 4});
                    oos.writeObject(pd);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            });
            add(myButton);
            pack();
            setVisible(true);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(() -> new MyClient("localhost",1234));
    }
}