skylar 发表于 2015-06-24 09:24

Java Socket简单应用

Server.javapackage chat.ui;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

@SuppressWarnings("serial")
public class Server extends JFrame {

    private JScrollPane pane;
    private JTextArea textAreaShow;
    private ServerSocket serverSocket;
    private List<Socket> connectedSockets = new ArrayList<Socket>();

    public Server() {
      initFrame();
      int port = 8888;
      try {
            startServer(port);
      } catch (IOException e) {
            String text = "以端口号" + port + "启动Socket服务失败,检查端口是否被占用,并重新启动服务";
            textAreaShow.append(text);
      }
    }

    // 窗口初始化
    private void initFrame() {

      setTitle("服务端");
      setSize(500, 400);
      setMinimumSize(new Dimension(250, 200));

      setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
      addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                if (serverSocket != null) {
                  try {
                        serverSocket.close();
                  } catch (IOException e) {
                        e.printStackTrace();
                        System.exit(1);
                  }
                  System.exit(0);
                }
            }
      });

      // 重写JTextArea的append方法
      textAreaShow = new JTextArea() {
            @Override
            public void append(String str) {
                str = (new Date().toString()) + "" + str + "\n";
                super.append(str);
            }
      };
      textAreaShow.setEditable(false);
      textAreaShow.setLineWrap(true);
      textAreaShow.setWrapStyleWord(true);

      pane = new JScrollPane(textAreaShow,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

      add(pane);

      setVisible(true);
    }

    // 启动服务,等待客户端连接
    private void startServer(int port) throws IOException {
      ExecutorService executorService = Executors.newCachedThreadPool();
      serverSocket = new ServerSocket(port);
      Socket socket;
      textAreaShow.append("服务已启动,端口号" + port);
      while (true) {
            socket = serverSocket.accept();
            String connectedMsg = "端口号" + socket.getPort() + " 已连接";
            textAreaShow.append(connectedMsg);
            dispatchMessage(connectedMsg);
            connectedSockets.add(socket);
            executorService.execute(new ServerThread(socket));
      }
    }

    // 向各客个连接转发发送消息
    private void dispatchMessage(String str) {
      DataOutputStream dos;
      for (Socket soc : connectedSockets) {
            try {
                dos = new DataOutputStream(soc.getOutputStream());
                dos.writeUTF(str);
            } catch (IOException e) {
                e.printStackTrace();
            }
      }
    }

    // 处理各连接的线程
    private class ServerThread implements Runnable {

      private Socket socket;
      private DataInputStream in;

      public ServerThread(Socket socket) {
            this.socket = socket;
            try {
                in = new DataInputStream(socket.getInputStream());
            } catch (IOException e) {
                textAreaShow.append(e.getMessage());
            }
      }

      @Override
      public void run() {
            try {
                String str;
                while ((str = in.readUTF()) != null) {
                  str = socket.getPort() + "说:" + str;
                  textAreaShow.append(str);
                  dispatchMessage(str);
                }
            } catch (IOException e) {
                textAreaShow.append("Port " + socket.getPort() + " 已断开连接");
                connectedSockets.remove(socket);
                closeSocket();
            }
      }

      private void closeSocket() {
            if (in != null) {
                try {
                  in.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                  socket.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
            }
      }
    }

    public static void main(String[] args) {
      new Server();
    }
}Client.javapackage chat.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

@SuppressWarnings("serial")
public class Client extends JFrame {

    private JTextArea textAreaShow;
    private JTextField textFieldInput;
    private JButton buttonSend;
    private JScrollPane paneTop;
    private JPanel paneBottom;
    private Socket socket;
    private DataInputStream in;
    private DataOutputStream out;
    private String str;
    SendActionListener sendActionListener;

    public Client() {
      initFrame();
      connect();
    }

    private void initFrame() {

      setTitle("客户端");
      setSize(500, 400);
      setMinimumSize(new Dimension(250, 200));
      setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
      addWindowListener(new WindowExitListener());

      // 重写append方法,在前面加上日期和在末尾加上换行
      textAreaShow = new JTextArea() {
            @Override
            public void append(String str) {
                str = new Date().toString() + "   " + str + "\n";
                super.append(str);
            }
      };
      textAreaShow.setEditable(false);
      textAreaShow.setLineWrap(true);
      textAreaShow.setWrapStyleWord(true);

      SendActionListener sendActionListener = new SendActionListener();
      textFieldInput = new JTextField();
      textFieldInput.addActionListener(sendActionListener);
      buttonSend = new JButton("发送");
      buttonSend.addActionListener(new SendActionListener());

      paneTop = new JScrollPane(textAreaShow,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

      paneBottom = new JPanel(new BorderLayout());
      paneBottom.add(textFieldInput, BorderLayout.CENTER);
      paneBottom.add(buttonSend, BorderLayout.EAST);

      add(paneTop, BorderLayout.CENTER);
      add(paneBottom, BorderLayout.SOUTH);

      setVisible(true);
    }

    // 连接到服务,并得到输入输出流
    private void connect() {
      int port = 8888;
      try {
            socket = new Socket("localhost", port);
            textAreaShow.append("连接到服务,本地端口号" + socket.getLocalPort());
            setTitle("客户端" + socket.getLocalPort());
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());

            String message;
            while ((message = in.readUTF()) != null) {
                textAreaShow.append(message);
            }
      } catch (IOException e) {
            textAreaShow.append("连接异常");
            close();
      }
    }

    // 释放资源
    private int close() {
      int exitCode = 0;
      if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
                exitCode = 1;
            }
      }
      if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
                exitCode = 1;
            }

      }
      if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                exitCode = 1;
                e.printStackTrace();
            }
      }
      return exitCode;
    }

    // 响应关闭操作
    private class WindowExitListener extends WindowAdapter {
      @Override
      public void windowClosing(WindowEvent event) {
            System.exit(close());
      }
    }

    // 响应发送操作
    private class SendActionListener implements ActionListener {

      @Override
      public void actionPerformed(ActionEvent event) {
            str = textFieldInput.getText();
            try {
                out.writeUTF(str);
                textFieldInput.setText("");
            } catch (IOException e) {
                e.printStackTrace();
            }
      }

    }

    public static void main(String[] args) {
      new Client();
    }

}捕获.PNG   


页: [1]
查看完整版本: Java Socket简单应用