Socket技术二(一个服务器,多个客户端)
??????? 主要用到线程和线程池。没个客户端访问都要启动一个线程,然后将其存放在线程池中。这样就实现了多个用户的同时访问!
??????? 启动一个服务器,三个客户端,将其发送是信息分别为“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);//启动监听,端口为22222exec = 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();}}
?
?
下一篇将是客户端与客户端交互信息。
?