我们应该比较了解TCP/UDP,想什么应表会传网数物的计算器的七层协议,还有TCP的三次握手,四次回收,UDP的广播流,不保证收到,跳过这些基础,我们直接来看java如何实现的
先来看一下tcp,记得想要发送的时候flush一下,这样就会把输出流写入到网络中:
首先编写Server端
import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; class SocketHandler extends Thread { private Socket socket = null; // 将连接出手啊 public SocketHandler(Socket s) { this.socket = s; } @Override public void run() { // 获取这个连接输入流 try (InputStream input = this.socket.getInputStream()) { // 获取这个连接的输出流 try (OutputStream output = this.socket.getOutputStream()) { // 调用方法进行处理 hand(input, output); } } catch (IOException e) { try { // 如果断开连接或者io错误,尝试关闭连接 this.socket.close(); } catch (IOException ex) { ex.printStackTrace(); } e.printStackTrace(); } System.out.println("客户端结束连接"); } private void hand(InputStream input, OutputStream ouput) throws IOException { // 将输入输出放在内存,这个也可以存入文件 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ouput, StandardCharsets.UTF_8)); BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); // 先打声招呼 writer.write("欢迎光临"); writer.newLine(); // 强制发送消息 writer.flush(); while (true) { // 接受一行消息 String s = reader.readLine(); System.out.println(s); // 如果输入的是 exit 就退出 if (s.equals("exit")) { writer.write("再见"); writer.newLine(); writer.flush(); break; } // 否则就让他继续发 writer.write("请继续"); writer.newLine(); writer.flush(); } } } public class Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8090); // 指定监听端口 // 起一个循环,来不停的接受请求 while (true) { Socket s = server.accept(); // 接收连接 System.out.println(s.getRemoteSocketAddress()); // 获取客户端地址 // 起一个线程来处理这次连接 Thread t = new SocketHandler(s); t.start(); } } }
server就是起了一个无限循环,来接受客户端的连接
接下来看一下客户端实现:
import java.io.*; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Client { public static void main(String[] args) throws IOException { Socket sock = new Socket("127.0.0.1", 8090); // 连接客户端 // 获取输入输出流并进一步处理 try (InputStream input = sock.getInputStream()) { try (OutputStream output = sock.getOutputStream()) { hand(input, output); } } catch (IOException e) { e.printStackTrace(); } sock.close(); System.out.println("客户端退出"); } private static void hand(InputStream input, OutputStream ouput) throws IOException { // 将输入输出放在内存, BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(ouput, StandardCharsets.UTF_8)); BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); // 从终端读取消息 Scanner s = new Scanner(System.in); System.out.println("接收到>>" + reader.readLine()); while (true) { // 接受一行消息 System.out.println("请输入:>>"); // 如果输入的是 exit 就退出 String st = s.nextLine(); writer.write(st); writer.newLine(); writer.flush(); String recv = reader.readLine(); System.out.println("接收到>>" + recv); // 否则就让他继续发 if (recv.equals("再见")) { break; } } } }
UDP更简单一些,他不知道客户端从哪里来,有消息我就接受,并返回
Server端:
import java.io.*; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.nio.charset.StandardCharsets; public class Server { public static void main(String[] args) throws IOException, InterruptedException { DatagramSocket server = new DatagramSocket(8090); // 指定监听端口 // 起一个循环,来不停的接受请求 while (true) { byte[] b = new byte[1024]; DatagramPacket p = new DatagramPacket(b, b.length); server.receive(p); // 接收连接 String s = new String(p.getData(), p.getOffset(), p.getLength(), StandardCharsets.UTF_8); System.out.println(s); // Thread.sleep(2000); byte[] m = "recv".getBytes(); // 接受数据直接返回 p.setData(m); server.send(p); } } }
Client端
import java.io.*; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class Client1 { public static void main(String[] args) throws IOException { DatagramSocket sock = new DatagramSocket(); // 起一个实例化 sock.setSoTimeout(1000); // 设置超时时间 sock.connect(InetAddress.getByName("127.0.0.1"), 8090); // 去连接 Scanner s = new Scanner(System.in); // 循环发送 while (true) { System.out.println(">>>"); String ss = s.nextLine(); byte[] b = ss.getBytes(); // 消息需要打包 DatagramPacket p = new DatagramPacket(b, b.length); sock.send(p); byte[] recv = new byte[1024]; DatagramPacket p1 = new DatagramPacket(recv, recv.length); sock.receive(p1); String s1 = new String(p1.getData(), p1.getOffset(), p1.getLength(), StandardCharsets.UTF_8); System.out.println(s1); } } }