创建一个客户端:package Socket;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;/*
聊天案例客户端
*/
public class Client {private Socket socket;/** 构造方法用于初始化客户端* */public Client() {try {/** 实例化Socket时需要指定两个信息* 1、服务端Ip地址,如果链接的是本机,则使用localhost即可* 2、服务端口,用来找到运行在服务端计算机上的服务端应用程序** 实例化Socket的过程就是与服务端建立连接的过程,如果链接失败* 则会抛出异常* */System.out.println("正在链接服务端。。。");socket= new Socket("localhost",8088);System.out.println("与服务端建立链接成功!");} catch (IOException e) {e.printStackTrace();}}/** 客户端开始工作的方法* */public void start(){try {/*Socket提供的重要方法:OutputStream getOutputStream()* 该方法用于获取一个字节输出流,用于向服务端发送数据* */OutputStream outputStream=socket.getOutputStream();/*//向服务端发送一个字节数据:00000001outputStream.write(1);*/while (true){System.out.println("输入要发送的内容:");Scanner scan=new Scanner(System.in);String str= scan.nextLine();if ("exit".equalsIgnoreCase(str)){break;}//用字符串表示发送的内容//String str="你能学会java吗?";//将字符串转换成字节数组byte[] data=str.getBytes(StandardCharsets.UTF_8);//先给服务端发送字节数组的字节数量,也就是要发送多少字节outputStream.write(data.length);//在将字符串转换的所有字节发送给服务端outputStream.write(data);}} catch (IOException e) {e.printStackTrace();}finally {try {/** 当通讯完毕时,希望与对方断开链接应当调用close方法* 1、close方法会关闭字节输入流和字节输出流* 2、与对方进行四次挥手* */socket.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String[] args) {Client client=new Client();client.start();}
}创建一个服务端:
package Socket;import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*
* 聊天程序服务端
* */
public class Server {/**运行在服务端的ServerSocket* 主要工作:* 1、向系统申请服务端口* 2、监听该端口,一旦客户端通过该端口尝试链接则创建Socket与客户端建立链接*/private ServerSocket serverSocket;private ExecutorService threadPool;/** 构造方法* */public Server(){try {System.out.println("正在启动!");serverSocket=new ServerSocket(8088);threadPool= Executors.newFixedThreadPool(20);System.out.println("启动完成");} catch (IOException e) {e.printStackTrace();}}public void start(){/** accept: 接受** ServerSocket提供的方法:accept用于接受客户端的链接该方法是一个阻塞方法,调用后程序"卡主",开始等待客户端的链接,一旦一个客户端链接,该方法会立即返回一个Socket对象用于与该客户端进行数据交互。* */try {while (true){System.out.println("等待客户端链接");Socket socket = serverSocket.accept();System.out.println("一个客户端已连接");//启动一个线程来处理该客户端交互ClientHandler handler=new ClientHandler(socket);/* Thread t=new Thread(handler);t.start();*/threadPool.execute(handler);}} catch(IOException e){e.printStackTrace();}}public static void main(String[] args) {Server server=new Server();server.start();}private class ClientHandler implements Runnable{private Socket socket;public ClientHandler(Socket socket){this.socket=socket;}public void run(){/** Socket提供的额方法:* InputStream getInputStream()* 获取该Socket的输入流,用于读取对方发送的信息* */try {InputStream inputStream = socket.getInputStream();//读一个字节,得知客户端后续发送了多少个字节int len;/** 通过网络流读取对方发送过来的一个字节数据时* 如果返回值为-1仍然是表达流读取到了末尾,此时只有当客户端正常断开* 链接(进行了四次挥手时)read读到了-1* */while ((len=inputStream.read())!=-1) {//创建字节数组,存储客户端发送的字节byte[] data = new byte[len];//读数据inputStream.read(data);//将数据转换成字符串String message = new String(data, StandardCharsets.UTF_8);System.out.println("客户端内容:" + message);}} catch (IOException e) {e.printStackTrace();}}}
}