Socket通信程序实现,开发环境:
(1)Window8
(2)JDK7.0
(3)Eclipse
目录结构如图所示:
business包:存放业务实现类
util包:存放系统的使用工具类,为其他包提供使用
window包:存放系统的图形界面窗口类
一、window包,新建类,服务器窗口类ServerFrame.java和客户端窗口类ClientFrame.java
(1)服务器窗口类ServerFrame.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 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()); }}
二、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"; }
三、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(); } }
有一个小小的问题可以继续深入,上面只是针对一个客户端的连接请求,如果需要实现多客户的连接请求,应该怎么去处理?