Socket又称为套接字,因为它使用的时候都是和一个端口连接在一起,一个端口使用一个数字表示。Socket做为连接双向数据通道的断点,常用来编写客户机/服务器应用程序。下面我们使用Socket编程实现服务器和客户端聊天窗口。服务器首先建立一个ServerSocket,以指定端口号和监听客户机的请求,还有建立一个Socket来建立与客户机的通信。客户机则要建立套接到同一个端口的Socket来与服务器端通信。
下面是服务器端的程序:
package net; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Server extends Frame implements ActionListener{ Label label=new Label("交谈"); Panel panel=new Panel(); TextField tf=new TextField(10); TextArea ta=new TextArea(); ServerSocket server; Socket client; InputStream in; OutputStream out; public Server() { super("服务器"); setSize(250,250); panel.add(label); panel.add(tf); tf.addActionListener(this); add("North",panel); add("Center",ta); addWindowFocusListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); setVisible(true); try { server=new ServerSocket(4000); //指定端口号 client=server.accept(); //使用ServerSocket的accept方法得到Socket ta.append("已连接的客户机:"+client.getInetAddress().getHostName()+"\n\n"); in=client.getInputStream(); out=client.getOutputStream(); } catch (Exception e) { e.printStackTrace(); } while(true) { try { byte[] buf=new byte[256]; in.read(buf); String str=new String(buf); ta.append("客户机说:"+str); ta.append("\n"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } public void actionPerformed(ActionEvent e) { try { String str=tf.getText(); byte[] buf=str.getBytes(); out.write(buf); tf.setText(""); ta.append("我说:"+str); ta.append("\n"); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } public static void main(String[] arg0) { new Server(); } }
客户端程序:
package net; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Client extends Frame implements ActionListener{ Label label=new Label("交谈"); Panel panel=new Panel(); TextField tf=new TextField(10); TextArea ta=new TextArea(); Socket client; InputStream in; OutputStream out; public Client() { super("客户端"); setSize(250,250); panel.add(label); panel.add(tf); tf.addActionListener(this); add("North",panel); add("Center",ta); addWindowFocusListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { // TODO Auto-generated method stub System.exit(0); } }); setVisible(true); try { client=new Socket(InetAddress.getLocalHost(), 4000); //因为是在自己的机器上使用所以用InetAddress的静态方法getLocalHost方法得到主机 ta.append("已连接到服务器:"+client.getInetAddress().getHostName()+"\n\n"); in=client.getInputStream(); out=client.getOutputStream(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } while(true) { try { byte[] buf=new byte[256]; in.read(buf); String str=new String(buf); ta.append("服务器说:"+str); ta.append("\n"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub try { String str=tf.getText(); byte[] buf=str.getBytes(); out.write(buf); tf.setText(""); ta.append("我说:"+str); ta.append("\n"); } catch (Exception e2) { // TODO: handle exception e2.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub new Client(); } }
运行时需要注意的是要先运行服务器端,然后再运行客户机端,不然会报错。运行结果截图: