本Demo是在CSDN的其他一篇关于Socket通信的Demo基础上,利用多线程实现了服务端与客户端的相互通信。
原Demo博客的地址https://blog.csdn.net/qiuyoungster/article/details/58030191
第一次在CSDN发博客,还有很多不懂的地方,望大佬们多多指点。
package com.lvjia.car.socket; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Server { private ServerSocket serverSocket; private final Map socketMap=new HashMap(); private final Map clientSizeMap=new HashMap(); public Server(){ try{ serverSocket = new ServerSocket(8088); }catch(Exception e){ e.printStackTrace(); } } public void start(){ try{ Socket socket = null; new Thread(new Runnable() {//创建一条线程,向客户端发送消息 @Override public void run() { Scanner scanner = new Scanner(System.in); while(true){ String demo=scanner.nextLine(); String[] demoArray=demo.split("/:"); String socketIp=demoArray[0]; String info=demoArray[1]; System.out.println("服务端输入的ip:"+socketIp); System.out.println("服务端发送的消息:"+info); Socket socket=(Socket)socketMap.get(socketIp); try{ OutputStream out = socket.getOutputStream(); //OutputStreamWriter osw = new OutputStreamWriter(out, true); OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8"); PrintWriter pw = new PrintWriter(osw, true); pw.println("你好!客户端!"); //创建Scanner读取用户输入内容 //scan.nextLine(); pw.println(info); }catch(Exception e){ e.printStackTrace(); } } } }).start(); //serverSocket.accept() 方法会产生阻塞,直到某个Socket连接,返回请求连接的Socket while ((socket = serverSocket.accept())!=null){//每当有新的客户端连接到服务器,便创建一条线程,获取连接到服务端的客户端,并将之socket保存在Map集合中 final Socket socket1 = socket; socketMap.put(socket1.getInetAddress().getHostAddress(),socket1); System.out.println("==========================================="); System.out.println("有新的连接,新连接的客户端Ip:"+socket1.getInetAddress().getHostAddress()); System.out.println("当前连接的客户端总数:"+socketMap.size()+"条"); Integer clientsize=socketMap.size(); clientSizeMap.put(socket1.getInetAddress().getHostAddress(),clientsize); new Thread(new Runnable() { @Override public void run() { System.out.println("客户端"+clientsize+"已连接!"); System.out.println("==========================================="); try { Integer number =(Integer) clientSizeMap.get(socket1.getInetAddress().getHostAddress()); InputStream in = socket1.getInputStream(); InputStreamReader isr = new InputStreamReader(in, "UTF-8"); BufferedReader br = new BufferedReader(isr); //不断读取客户端数据 while(true){ System.out.println("客户端"+number+"说:" + br.readLine()); } }catch (Exception e){ } } }).start(); } }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub Server server = new Server(); server.start(); } }
package com.lvjia.car.socket; import java.io.*; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Client { private Socket socket; public Client(){ try { socket = new Socket("localhost", 8088); } catch (Exception e) { e.printStackTrace(); } } public void start(){ final Socket socket1=this.socket; new Thread(new Runnable() {//创建一条线程,监听获取服务端发送的消息 @Override public void run() { try { InputStream in = socket1.getInputStream(); InputStreamReader isr = new InputStreamReader(in, "UTF-8"); BufferedReader br = new BufferedReader(isr); //System.out.println("客户端说:" + br.readLine()); //不断读取客户端数据 while(true){ System.out.println("服务端说:" + br.readLine()); } }catch (Exception e){ } } }).start(); try{//向服务端发送消息 OutputStream out = socket.getOutputStream(); //OutputStreamWriter osw = new OutputStreamWriter(out, true); OutputStreamWriter osw = new OutputStreamWriter(out, "UTF-8"); PrintWriter pw = new PrintWriter(osw, true); pw.println("你好!服务器!"); //创建Scanner读取用户输入内容 Scanner scanner = new Scanner(System.in); while(true){ //scan.nextLine(); System.out.println("尊敬的用户,请您输入:"); pw.println(scanner.nextLine()); } }catch(Exception e){ e.printStackTrace(); }finally{ if(socket != null){ try{ socket.close(); }catch(Exception e){ e.printStackTrace(); } } } } public static void main(String[] args) { // TODO Auto-generated method stub Client client = new Client(); client.start(); } }
分为服务器端和客户端
注意:在启动时,先启动Server,再启动Client
不然会报 java.net.ConnectException: Connection refused: connect 异常.
==========================
启动后,Server控制台:
Client控制台:
==========================
在客户端,客户端向服务端发送消息时,直接输入想要发送的消息,然后回车,就ok
在服务端,服务端想某个客户端发送消息时,格式为:该客户端IP+/:Hello CSDN。例如:127.0.0.1/:Hello CSDN
第一次发稿,有很多不足,希望可以相互交流学习。