Socket通訊程序實現,開發環境:
java
(1)Window8服務器
(2)JDK7.0
app
(3)Eclipsesocket
目錄結構如圖所示:
ide
business包:存放業務實現類工具
util包:存放系統的使用工具類,爲其餘包提供使用ui
window包:存放系統的圖形界面窗口類this
1、window包,新建類,服務器窗口類ServerFrame.java和客戶端窗口類ClientFrame.javaspa
(1)服務器窗口類ServerFrame.java:.net
package window; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.io.ObjectOutputStream; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import util.Constant; public class ServerFrame extends JFrame{ private JScrollPane scrollPane1; private JTextArea ta_show; private JPanel panel1; private JTextField tf_message; private JButton btn_send; private int SHOW_ROWS = 11; private ObjectOutputStream out; public ServerFrame(){ initComponents(); } private void initComponents(){ //create scrollPanel object scrollPane1 = new JScrollPane(); ta_show = new JTextArea(); panel1 = new JPanel(); tf_message = new JTextField(); btn_send = new JButton(); setTitle("服務器端"); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ thisWindowClosing(e); } }); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); //scrollPane1 { ta_show.setRows(SHOW_ROWS); ta_show.setEditable(false); scrollPane1.setViewportView(ta_show); } //add scrollPane to the container contentPane.add(scrollPane1, BorderLayout.NORTH); //panel1 { panel1.setLayout(new FlowLayout()); tf_message.setPreferredSize(new Dimension(320,25)); panel1.add(tf_message); btn_send.setText("發送"); btn_send.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ btn_sendActionPerformed(e); } }); panel1.add(btn_send); } //add panel1 to the container contentPane.add(panel1,BorderLayout.SOUTH); pack(); setLocationRelativeTo(getOwner()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } protected void btn_sendActionPerformed(ActionEvent e) { // TODO Auto-generated method stub try{ out.writeObject("服務器端>>" + tf_message.getText()); out.flush(); tf_message.setText(""); } catch(IOException ie){ ie.printStackTrace(); } } private void thisWindowClosing(WindowEvent e) { // TODO Auto-generated method stub if(out != null){ try{ out.writeObject(Constant.CONNECT_QUIT); out.flush(); } catch(IOException ie){ ie.printStackTrace(); } } } public void setOut(ObjectOutputStream out){ this.out = out; } public void display(String mess){ ta_show.append(mess + "\n"); ta_show.setCaretPosition(ta_show.getText().length()); } }
(2)客戶端窗口類ClientFrame.java:
package window; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.io.ObjectOutputStream; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import util.Constant; public class ClientFrame extends JFrame{ private JScrollPane scrollPane1; private JTextArea ta_show; private JPanel panel1; private JTextField tf_message; private JButton btn_send; private int SHOW_ROWS = 11; private ObjectOutputStream out; public ClientFrame(){ initComponents(); } private void initComponents(){ scrollPane1 = new JScrollPane(); ta_show = new JTextArea(); panel1 = new JPanel(); tf_message = new JTextField(); btn_send = new JButton(); setTitle("客戶端"); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ thisWindowClosing(e); } }); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); //scrollPane1 { ta_show.setRows(SHOW_ROWS); ta_show.setEditable(false); scrollPane1.setViewportView(ta_show); } //add scrollPane to the container contentPane.add(scrollPane1, BorderLayout.NORTH); //panel1 { panel1.setLayout(new FlowLayout()); tf_message.setPreferredSize(new Dimension(320,25)); panel1.add(tf_message); btn_send.setText("發送"); btn_send.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ btn_sendActionPerformed(e); } }); panel1.add(btn_send); } //add panel1 to the container contentPane.add(panel1,BorderLayout.SOUTH); pack(); setLocationRelativeTo(getOwner()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } protected void btn_sendActionPerformed(ActionEvent e) { // TODO Auto-generated method stub try{ out.writeObject("客戶端>>" + tf_message.getText()); out.flush(); tf_message.setText(""); } catch(IOException ie){ ie.printStackTrace(); } } private void thisWindowClosing(WindowEvent e) { // TODO Auto-generated method stub if(out != null){ try{ out.writeObject(Constant.CONNECT_QUIT); out.flush(); } catch(IOException ie){ ie.printStackTrace(); } } } public void setOut(ObjectOutputStream out){ this.out = out; } public void display(String mess){ ta_show.append(mess + "\n"); ta_show.setCaretPosition(ta_show.getText().length()); } }
2、util包新建類,Constant.java用於定義系統常量
系統常量類Constant.java:
package util; /* * Constant module,which other modules can call it */ public class Constant { //server host which provides client connetion public static final String SERVER_HOST = "127.0.0.1"; //listen port on which server can listen public static final int LISTEN_PORT = 8000; //connect quit signal public static final String CONNECT_QUIT = "quit"; }
3、business包中新建類,服務器端類Server.java和客戶端類Client.java
(1) 服務器端類Server.java:
package business; import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import util.Constant; import window.ServerFrame; public class Server { private ServerFrame frame; private ObjectOutputStream out; private ObjectInputStream in; private ServerSocket serverSocket; private Socket socket; private int counter = 1; public Server(){ frame = new ServerFrame(); frame.setVisible(true); startServer(); } private void startServer(){ try{ serverSocket = new ServerSocket(Constant.LISTEN_PORT,2); while(true){ //waiting for connection frame.display("等待鏈接......."); socket = serverSocket.accept(); //build connection frame.display("已與客戶端" + socket.getInetAddress().getHostName() + "創建鏈接!"); frame.display("---------------------------------------------"); out = new ObjectOutputStream(socket.getOutputStream()); frame.setOut(out); out.flush(); in = new ObjectInputStream(socket.getInputStream()); String message = ""; while(true){ try{ message = (String) in.readObject(); if( message.equals(Constant.CONNECT_QUIT)){ frame.setOut(null); break; } frame.display(message); } catch(Exception e){ e.printStackTrace(); } } //結束鏈接 frame.display("客戶端" + socket.getInetAddress().getHostName() + "中斷了鏈接!"); out.close(); in.close(); socket.close(); ++counter; } } catch(EOFException eof){ eof.printStackTrace(); } catch(IOException ie){ ie.printStackTrace(); } } public static void main(String[] args){ new Server(); } }
(2) 客戶端類Client.java:
package business; import java.io.EOFException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import util.Constant; import window.ClientFrame; public class Client { private ClientFrame frame; private ObjectOutputStream out; private ObjectInputStream in; private Socket socket; public Client(){ frame = new ClientFrame(); frame.setVisible(true); startClient(); } public void startClient(){ try{ //request to connect frame.display("鏈接中......"); socket = new Socket(Constant.SERVER_HOST,Constant.LISTEN_PORT); //connected frame.display("鏈接至:"+ socket.getInetAddress().getHostName()); frame.display("-----------------------------------------------"); out = new ObjectOutputStream(socket.getOutputStream()); frame.setOut(out); in = new ObjectInputStream(socket.getInputStream()); String message = ""; while(true){ try{ message = (String) in.readObject(); if(message.equals(Constant.CONNECT_QUIT)){ frame.setOut(null); break; } frame.display(message); } catch(Exception e){ e.printStackTrace(); } } //disconnected frame.display("服務器已經斷開!"); out.close(); in.close(); socket.close(); } catch(EOFException eof){ eof.printStackTrace(); } catch(IOException ie){ ie.printStackTrace(); } } public static void main(String[] args){ new Client(); } }
有一個小小的問題能夠繼續深刻,上面只是針對一個客戶端的鏈接請求,若是須要實現多客戶的鏈接請求,應該怎麼去處理?