[java]UDPベースのSocket通信Demo

27797 ワード

JAva授業のプログラミング作業:先生からのdemoに基づいてクライアントがサーバ側にデータを送信し、サーバ側がクライアントを受け入れてデータ放送を行うことを実現する.
全体の機能はチャットルームに似ていて、コード部分はあまり難しくありませんが、本機のテストでこのような問題が発生しました.
サービス側は,各SocketクライアントのIPをSetセットに格納することで,データを受け取るたびに現在のすべてのIPに転送する.しかし、本機のプレゼンテーションの時に開いているすべてのChatClientクライアントは同じIPで、どのようにテストしますか?
解決策は,本機のテスト時にサービス側が複数の異なるポートに転送すればよいということであり,このように走り出したクライアントは異なるポートで傍受を行う(ブロードキャストを実現するためだけに,実際のアプリケーションではIPで転送する).
 
クライアントコード:
  
import javax.print.attribute.HashPrintServiceAttributeSet;

import javax.swing.*;



import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.Toolkit;

import java.awt.event.*;

import java.io.*;

import java.net.*;

import java.util.*;



public class ChatClient extends JFrame {



    JTextArea contents = new JTextArea();

    JLabel label1 = new JLabel("     ");

    JTextField address = new JTextField();

    JLabel label2 = new JLabel("   ");

    JTextField username = new JTextField();

    JButton online = new JButton("  ");

    JButton offline = new JButton("  ");

    JTextField input = new JTextField();

    JButton send = new JButton("  ");



    boolean onlineFlag = false;



    public ChatClient() {

        super("Chat Client");



        contents.setEditable(false);

        getContentPane().add(contents);



        JPanel p1 = new JPanel();

        p1.setLayout(new FlowLayout(FlowLayout.LEADING));



        address.setPreferredSize(new Dimension(100, 28));

        username.setPreferredSize(new Dimension(80, 28));

        input.setPreferredSize(new Dimension(180, 28));



        p1.add(label1);

        p1.add(address);

        p1.add(label2);

        p1.add(username);

        p1.add(online);

        p1.add(offline);

        p1.add(input);

        p1.add(send);



        offline.setEnabled(false);

        send.setEnabled(false);



        getContentPane().add(p1, BorderLayout.SOUTH);



        addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent we) {

                onlineFlag = false;

                Map<String, Object> m1 = new HashMap<String, Object>();

                m1.put("time", new Date()); //     

                m1.put("username", getUsername());

                m1.put("onlineFlag", onlineFlag);



                send(getServerAddress(), 2222, m1);



                System.exit(0);

            }

        });



        ActionListener al = new ActionListener() {

            public void actionPerformed(ActionEvent ae) {

                String server = getServerAddress();

                if (server == null || server.length() == 0) {

                    JOptionPane.showMessageDialog(ChatClient.this, "        !");

                    return;

                }



                if (ae.getSource() == online) {

                    //          

                    if (!onlineFlag) {

                        onlineFlag = true;

                        Map<String, Object> m1 = new HashMap<String, Object>();

                        m1.put("time", new Date()); //     

                        m1.put("username", getUsername());

                        m1.put("onlineFlag", onlineFlag);

                        online.setEnabled(false);

                        offline.setEnabled(true);

                        send.setEnabled(true);

                        address.setEnabled(false);

                        username.setEnabled(false);

                        send(getServerAddress(), 2222, m1);



                    }

                } else {

                    //          

                    if (onlineFlag) {

                        onlineFlag = false;

                        Map<String, Object> m1 = new HashMap<String, Object>();

                        m1.put("time", new Date()); //     

                        m1.put("username", getUsername());

                        m1.put("onlineFlag", onlineFlag);

                        online.setEnabled(true);

                        offline.setEnabled(false);

                        send.setEnabled(false);

                        address.setEnabled(true);

                        username.setEnabled(true);

                        send(getServerAddress(), 2222, m1);

                    }

                }

            }

        };



        ActionListener al2 = new ActionListener() {

            public void actionPerformed(ActionEvent ae) {

                Map<String, Object> m1 = new HashMap<String, Object>();

                m1.put("time", new Date());

                m1.put("username", getUsername());

                m1.put("input", getInput());

                send(getServerAddress(), 2222, m1);

            }

        };



        send.addActionListener(al2);



        online.addActionListener(al);

        offline.addActionListener(al);



        // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setSize(720, 400);

        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();



        setLocation((d.width - 720) / 2, (d.height - 400) / 2);

        setVisible(true);



        new Thread() {

            public void run() {

                try {

                    //  2221                ,    ,    。

                    DatagramSocket rSocket = new DatagramSocket(2220);

                    while (true) {

                        byte[] buffer = new byte[1024 * 16];

                        DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);

                        rSocket.receive(recvPacket);

                        byte[] data = recvPacket.getData();

                        byte[] recvData = new byte[recvPacket.getLength()];

                        System.arraycopy(buffer, 0, recvData, 0, recvData.length);

                        //            Map   

                        Map<String, Object> map = convertByteArrayToMap(recvData);

                        if (map.containsKey("onlineFlag")) { //       

                            boolean b = (boolean) map.get("onlineFlag");

                            if (b) { //   

                                map.put("input", "  ");

                            } else { //   

                                map.put("input", "  ");

                            }

                        }

                        Date time = (Date) map.get("time");

                        String s = convertDateToFormatString(time);

                        String user = (String) map.get("username");

                        user = "[" + user + "]";

                        contents.append(s + user + ": " + (String) map.get("input") + "\r
"); } } catch (Exception e) { e.printStackTrace(); } } }.start(); } public String getServerAddress() { String s = address.getText(); //trim s = s.trim(); return s; } public String getUsername() { String s = username.getText(); s = s.trim(); if (s == null || s.length() == 0) { s = " "; } return s; } public String getInput() { String s = input.getText(); s = s.trim(); if (s == null || s.length() == 0) { s = " "; } return s; } public static String convertDateToFormatString(Date d) { return new java.text.SimpleDateFormat("(yyyy-MM-dd HH:mm:ss)").format(d); } public static void send(String ip, int port, Map<String, Object> map) { try { byte[] data = convertMapToByteArray(map); DatagramSocket socket = new DatagramSocket(); DatagramPacket packet = new DatagramPacket(data, data.length); packet.setSocketAddress(new InetSocketAddress(ip, port)); socket.send(packet); } catch (Exception e) { e.printStackTrace(); } } public static byte[] convertMapToByteArray(Map<String, Object> map) { try { // , map ByteArrayOutputStream b = new ByteArrayOutputStream(); ObjectOutputStream ois = new ObjectOutputStream(b); ois.writeObject(map); byte[] temp = b.toByteArray(); return temp; } catch (Exception e) { e.printStackTrace(); } return null; } public static Map<String, Object> convertByteArrayToMap(byte[] data) { try { ByteArrayInputStream bais = new ByteArrayInputStream(data); ObjectInputStream ois = new ObjectInputStream(bais); Map<String, Object> result = (Map<String, Object>) ois.readObject(); return result; } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { new ChatClient(); } }

 
サービス側コード:
import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetSocketAddress;



import java.util.*;

import java.util.concurrent.LinkedBlockingQueue;



public class ChatServer {



    LinkedBlockingQueue<Map<String, Object>> queue = new LinkedBlockingQueue<Map<String, Object>>();

    Set<String> onlineIPs = new HashSet<String>(); //     IP。



    public ChatServer() {

        try {



            new Thread() {

                public void run() {

                    while (true) {

                        try {

                            //    ,            ,    IP  ,     IP    



                            if( !queue.isEmpty() ){

                                if( !onlineIPs.isEmpty() ){

                                    for(String ip : onlineIPs){

                                        //             ,     2220                     

                                        ChatClient.send(ip, 2221, queue.peek() );

                                        ChatClient.send(ip, 2220, queue.remove() );

                                    }    

                                }

                            }

                            

                            //end

                        } catch (Exception e) {

                            e.printStackTrace();

                        }

                    }

                }

            }.start();

            //    2222

            DatagramSocket serverSocket = new DatagramSocket(2222);

            System.out.println("Chat Server started.");

            while (true) {

                byte[] buffer = new byte[1024 * 16];

                DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);



                serverSocket.receive(recvPacket);



                InetSocketAddress remoteAddress = new InetSocketAddress(recvPacket.getAddress(),

                        recvPacket.getPort());

                System.out.println("    " + remoteAddress.getHostString() + "         ");



                byte[] data = recvPacket.getData();

                byte[] recvData = new byte[recvPacket.getLength()];

                System.arraycopy(buffer, 0, recvData, 0, recvData.length);

                System.out.println(recvData.length);

                Map<String, Object> map = ChatClient.convertByteArrayToMap(recvData);

                System.out.print("map  "+map.size());

                if (map.containsKey("onlineFlag")) { //       

                    boolean b = (boolean) map.get("onlineFlag");

                    if (b) { //   

                        onlineIPs.add(remoteAddress.getHostString());

                    } else { //   

                        onlineIPs.remove(remoteAddress.getHostString());

                    }

                }



                queue.add(map);



            }



        } catch (Exception e) {

            e.printStackTrace();

        }

    }



    public static void main(String[] args) {

        new ChatServer();



    }



}