JAVA socketJava学习笔记程序员

Java实现Socket网络编程(二)

2016-04-09  本文已影响797人  Louis_陆

在看到本文之前,如果读者没看过笔者的前文Java实现Socket网络编程(一) ,请先翻阅。在阅读本文前,读者应先具备Java的Swing编程的基础知识。

首先,我们编写服务器的界面:

        JFrame mainFrame = new ServerMain();
        mainFrame.setTitle("server");
        mainFrame.setSize(545, 395);
        // 设置显示位置为正中间
        mainFrame.setLocationRelativeTo(null);
        // 设置布局文件为空,以让组件可使用绝对布局setBounds
        mainFrame.setLayout(null);
        // 大小不可变
        mainFrame.setResizable(false);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setVisible(true);
        // 设置IPAddress标签
        JLabel jlIP = new JLabel("IPAddress:");
        jlIP.setBounds(10, 15, 70, 25);
        add(jlIP);

        // 设置IPAddress显示文本
        JTextField jtfIP = new JTextField();
        jtfIP.setText("127.0.0.1");
        jtfIP.setEditable(false);
        jtfIP.setBounds(80, 15, 185, 25);
        jtfIP.setText(Common.IP);
        add(jtfIP);

        // 设置Port标签
        JLabel jlPort = new JLabel("Port:");
        jlPort.setBounds(10, 50, 70, 25);
        add(jlPort);

        // 设置Port显示文本
        JTextField jtfPort = new JTextField();
        jtfPort.setText("10055");
        jtfPort.setEditable(false);
        jtfPort.setBounds(80, 50, 185, 25);
        jtfPort.setText(Common.PORT + "");
        add(jtfPort);

        // 设置Client标签
        JLabel jlClient = new JLabel("Choose Client:");
        jlClient.setBounds(15, 90, 100, 25);
        add(jlClient);

        // 创建Client列表
        model = new DefaultListModel<>();
        clientList = new JList<String>(model);
        clientList.setBorder(BorderFactory.createLineBorder(Color.black));
        // 设置多选模式
        clientList
                .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        clientList.setFocusable(true);

        // 添加滚动
        jpclientList = new JScrollPane(clientList);
        jpclientList.setBounds(10, 115, 255, 65);
        add(jpclientList);

        // 设置Send Message标签
        JLabel jlSendMessage = new JLabel("Send Message:");
        jlSendMessage.setBounds(15, 185, 100, 25);
        add(jlSendMessage);

        // 设置Send Message文本
        jtaSendMessage = new JTextArea();
        // 激活自动换行功能
        jtaSendMessage.setLineWrap(true);
        // 激活断行不断字功能
        jtaSendMessage.setWrapStyleWord(true);
        // 设置黑色边框
        jtaSendMessage.setBorder(BorderFactory.createLineBorder(Color.black));
        // 添加滚动条
        JScrollPane jpSendMessage = new JScrollPane(jtaSendMessage);
        jpSendMessage.setBounds(10, 210, 255, 100);
        add(jpSendMessage);

        // 设置Connect标签
        jlConnect = new JLabel("0 Connect success.");
        jlConnect.setBounds(15, 320, 130, 25);
        add(jlConnect);

        // 设置Send Message按钮
        JButton jbSendMessage = new JButton("SendMessage");
        jbSendMessage.setBounds(145, 320, 120, 25);

        add(jbSendMessage);

        // 设置Received Message标签
        JLabel jlReceivedMessage = new JLabel("Received Message:");
        jlReceivedMessage.setBounds(295, 15, 130, 25);
        add(jlReceivedMessage);

        // 设置Received Message文本
        jtaReceivedMessage = new JTextArea();
        // 激活自动换行功能
        jtaReceivedMessage.setLineWrap(true);
        // 激活断行不断字功能
        jtaReceivedMessage.setWrapStyleWord(true);
        // 设置不可编辑
        jtaReceivedMessage.setEditable(false);
        // 设置黑色边框
        jtaReceivedMessage.setBorder(BorderFactory
                .createLineBorder(Color.black));
        // 添加滚动条
        JScrollPane jpReceivedMessage = new JScrollPane(jtaReceivedMessage);
        jpReceivedMessage.setBounds(285, 40, 230, 305);
        add(jpReceivedMessage);

然后,我们编写客户端界面:因客户端界面和服务器界面大体相似,笔者在此处就不粘贴代码了。值得注意的是,客户端和服务器应是两个不同的Java Project。

根据设计思路,我们为服务器创建一个ServerSocket,监听4703端口,并启动一个主监听线程,监测是否有客户端连接。

        try {
            // 创建监听4703端口的ServerSocket
            serverSocket = new ServerSocket(Common.PORT);

            // 启动一个监听线程
            listenThread = new Thread(new ListenThread());
            listenThread.start();
        } catch (Exception e1) {
            e1.printStackTrace();
        }

实际上,可采用大于1024的任意端口,笔者选用4703端口,是因为此端口很少被占用,能在不同的机器上运行时不会产生端口冲突。小于1024的端口都是绑定给特定的服务,所以一般除了那些专门提供某服务的软件可以用,别的软件一般不用。

下面,我们来实现服务器主监听线程ListenThread:

        // 响应一个请求
        Socket clientSocket = ServerMain.serverSocket.accept();

        // 创建一个子线程和客户端保持连接
        new Thread(new ServerReceiverThread(clientSocket)).start();

        // 添加到Socket请求队列
        HashMap<Socket, Boolean> map = new HashMap<Socket, Boolean>();
        map.put(clientSocket, false);
        clientSockets.add(map);

通过ServerSocket的accept()方法,去响应一个连接请求,并创建一个与客户端交互的Socket对象,把Socket对象添加到请求队列,为后期发送消息做准备。同时创建一个子线程,用于接收客户端消息。

上一篇 下一篇

猜你喜欢

热点阅读