主要用到线程和线程池。没个客户端访问都要启动一个线程,然后将其存放在线程池中。这样就实现了多个用户的同时访问!
启动一个服务器,三个客户端,将其发送是信息分别为“send1”“send2”“send3”。运行结果为:
server控制台:send1
send2
send3
send1客户端:已收到信息为:send1
send2客户端:已收到信息为:send2
send3客户端:已收到信息为:send3
package testSocket_Thread; 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.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { ServerSocket server; //其方法accept 用来监听客户端的链接 Socket socket; static List<Socket> list = new ArrayList<Socket>();//保存链接的Socket对象 ExecutorService exec; //线程池类(说白了就是存放线程用的) //1. Executors.newCachedThreadPool()缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中 //2. execute(Runnable r) 其实就是对Runnable对象调用start()方法 //3. exec.shutdownNow(); 一旦执行,线程将从线程池消失(客户端) public Server(){ try { server = new ServerSocket(22222);//启动监听,端口为22222 exec = Executors.newCachedThreadPool(); while(true) { socket = server.accept(); list.add(socket); exec.execute(new Tast(socket)); } } catch (IOException e) { e.printStackTrace(); } } class Tast implements Runnable { Socket socket; //服务器端Socket对象 DataInputStream in; //数据输入输出流 DataOutputStream ou; public Tast(Socket socket) throws IOException{ this.socket = socket; in = new DataInputStream(socket.getInputStream()); //获取Socket中的出入输出流,以完成通信 ou = new DataOutputStream(socket.getOutputStream()); } public void run() { try { //---------- 这里可以换成任何数据包的接受和发送 ---------- String receive = in.readUTF(); //读取客户端信息 ou.writeUTF("已收到信息为:"+receive);//向客户端发送信息 //注意:读取和发送的顺序不能错 ou.close(); in.close(); socket.close(); System.out.println(receive); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { new Server(); } }
package testSocket_Thread; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Client { static ExecutorService exec = Executors.newCachedThreadPool(); public Client() { try { Socket socket = new Socket("127.0.0.1", 22222); exec.execute(new Sender(socket)); } catch (Exception e) { e.printStackTrace(); } } class Sender implements Runnable { Socket socket; //客户端Socket对象 DataInputStream in; //输入输出流 DataOutputStream ou; public Sender(Socket s){ socket = s; } public void run() { try { in = new DataInputStream(socket.getInputStream());//获取Socket中的出入输出流,以完成通信 ou = new DataOutputStream(socket.getOutputStream()); //---------- 这里可以换成任何数据包的接受和发送 ---------- ou.writeUTF("send2"); //向服务器端发送信息 String receive = in.readUTF(); //接受服务器的反馈信息 in.close(); ou.close(); socket.close(); //exec.shutdownNow(); 一旦执行,线程将从线程池消失 System.out.println(receive); }catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { new Client(); } }
下一篇将是客户端与客户端交互信息。