1.1 URL及其应用
URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。
URL 解析:
协议为(protocol):http
主机为(host:port):www.fuxian.org
端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。
文件路径为(path):/index.html
请求参数(query):language=cn
定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。
构造方法:
常用方法:
package com.fuxian.url; import java.net.MalformedURLException; import java.net.URL; public class TestURL { public static void main(String[] args) { try { URL url = new URL("https://www.cnblogs.com/LEPENGYANG/p/15060223.html"); System.out.println("URL为:" + url.toString()); System.out.println("协议为:" + url.getProtocol()); System.out.println("验证信息为:" + url.getAuthority()); System.out.println("文件名及请求参数为:" + url.getFile()); System.out.println("主机名:" + url.getHost()); System.out.println("路径为:" + url.getPath()); System.out.println("端口为:" + url.getPort()); System.out.println("默认端口为:" + url.getDefaultPort()); System.out.println("请求参数为:" + url.getQuery()); System.out.println("定位位置为:" + url.getRef()); } catch (MalformedURLException e) { e.printStackTrace(); } } }
1.2 InetAddress及其应用
InetAddress在java.net包下,主要用于IP地址和域名
常用方法:
package com.fuxian.url; import java.net.InetAddress; import java.net.UnknownHostException; public class TestInetAddress { public static void main(String[] args) { try { InetAddress byAddress = InetAddress.getByName("www.fuxian.org"); System.out.println("博客域名:" + byAddress.getHostName()); System.out.println("博客的IP地址:" + byAddress.getHostAddress()); InetAddress localHost = InetAddress.getLocalHost(); System.out.println("本地IP地址:" + localHost.getHostName()); System.out.println("本地IP地址:" + localHost.getHostAddress()); } catch (UnknownHostException e) { e.printStackTrace(); } } }
1.3 Socket通信-单向通信
TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP/IP
Socket套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。
当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信
java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
服务器端建立步骤
1:建立服务器端套接字,指定监听端口
2:监听,等待客户端请求,并愿意接受连接
3:获取Socket的输出流,并使用缓冲流进行包装
4:向客户端发送反馈信息
5:关闭流及Socket连接
客户端建立步骤:
1:创建一个Socket对象
2:获取Socket的输入流,并使用缓冲流进行包装
3接收服务器端发送的信息
4:关闭流及Socket连接
1.4 Socket通信-多向通信
服务器端建立步骤:
1:建立服务器端套接字,指定监听端口
2:监听,等待客户端请求,并愿意接受连接
3:获取Socket的输入流,并使用缓冲流进行包装
4:获取Socket的输出流,并使用缓冲流进行包装
5:获取客户端发送的数据
6:向客户端发送反馈信息
7:关闭流及Socket连接
package com.fuxian.url; import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class DoubleServer { public static void main(String[] args) { Socket socket = null; BufferedWriter bufferedWriter = null; BufferedReader bufferedReader = null; try { //1.建立服务器端套接字,指定监听端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器端启动成功了!"); //2.监听,等待客户端请求,并愿意接受连接 socket = serverSocket.accept(); //添加内容:从输入流中读取客户端发送过来的数据 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = bufferedReader.readLine(); System.out.println("从客户端发送过来的数据:" + line); //3.socket的输出流,并使用缓冲流进行包装 bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); //4.向客户端发送反馈信息 bufferedWriter.write("这是服务器发送的数据,你收到了吗?"); } catch (IOException e) { e.printStackTrace(); } finally { //5:关闭流及Socket连接 try { if (bufferedWriter != null) bufferedWriter.close(); if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
客户端建立步骤:
1:创建一个Socket对象
2:获取Socket的输出流,并使用缓冲流进行包装
3:获取Socket的输入流,并使用缓冲流进行包装
4:向服务器端发送数据
5:接收服务器端发送的信息
6:关闭流及Socket连接
package com.fuxian.url; import java.io.*; import java.net.Socket; public class DoubleClient { public static void main(String[] args) { Socket socket = null; BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { //1.创建一个Socket对象 socket = new Socket("127.0.0.1", 8888); //添加内容:向服务器发送一句话 bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write("这是客户端向服务器端发送的数据 "); bufferedWriter.flush(); bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //2.获取Socket的输入流,并使用缓冲流进行包装 //3.接受服务器端发送的信息 String line = bufferedReader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } finally { //4.关闭流及Socket连接 try { if (bufferedReader != null) bufferedReader.close(); if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
1.5 Socket通信-多线程下的多客户端通信
服务器端建立步骤:
1:建立服务器端套接字,指定监听端口
2:在死循环中开启监听,等待客户端请求,并愿意接受连接
3:开启线程对Socket进行处理
a:获取Socket的输入流,并使用缓冲流进行包装
b:获取Socket的输出流,并使用缓冲流进行包装
c:获取客户端发送的数据
d:向客户端发送反馈信息
e:关闭流及Socket连接
package com.jh.socketPackage; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ThreadServer { public static void main(String[] args) { //1.建立服务器端套接字,指定监听端口 ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8888); System.out.println("服务器启动成功了!"); } catch (IOException e) { System.err.println("服务器监听失败!"); } while (true) { try { Socket socket = serverSocket.accept(); //开启线程处理这个socket Task task = new Task(socket); task.start(); } catch (IOException e) { e.printStackTrace(); } } } }
package com.jh.socketPackage; import java.io.*; import java.net.Socket; public class Task extends Thread { private Socket socket; public Task() { } public Task(Socket socket) { this.socket = socket; } @Override public void run() { //处理socket套接字 BufferedReader bufferedReader = null; BufferedWriter bufferedWriter = null; try { System.out.println("有客户端连接了!"); //添加内容:从输入流中读取客户端发送过来的数据 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = bufferedReader.readLine(); System.out.println("客户端发送过来的数据:" + line); //3.获取Socket的输出流,并使用缓冲流进行包装 bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write("这是服务器发送的数据,你收到了吗?"); bufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); if (bufferedReader != null) bufferedReader.close(); if (bufferedWriter != null) bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
客户端建立步骤:
将以下步骤放入线程的run方法中处理
1:创建一个Socket对象
2:获取Socket的输出流,并使用缓冲流进行包装
3:获取Socket的输入流,并使用缓冲流进行包装
4:向服务器端发送数据
5:接收服务器端发送的信息
6:关闭流及Socket连接
package com.jh.socketPackage; import sun.security.mscapi.CPublicKey; import java.io.*; import java.net.Socket; public class DoubleClient { public static void main(String[] args) { long start = System.currentTimeMillis(); //起始的毫秒数 // client("1"); // client("2"); // client("3"); // client("4"); // client("5"); new ThreadClient("1").start(); new ThreadClient("2").start(); new ThreadClient("3").start(); new ThreadClient("4").start(); new ThreadClient("5").start(); long end = System.currentTimeMillis(); //结束的毫秒数 System.out.println(end-start); } public static void client(String name) { Socket socket = null; BufferedWriter bufferedWriter = null; BufferedReader bufferedReader = null; try { //1.创建一个Socket对象 socket = new Socket("127.0.0.1", 8888); bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); //2.获取Socket的输入流,并使用缓冲区进行包装 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //添加内容:向服务器发送数据 bufferedWriter.write("这是"+name+"客户端向服务器端发送的数据 "); bufferedWriter.flush(); //3.接受服务器端发送的信息 String line = bufferedReader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); if (bufferedReader != null) bufferedReader.close(); if (bufferedWriter != null) bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
package com.jh.socketPackage; import java.io.*; import java.net.Socket; public class ThreadClient extends Thread { private String name; public ThreadClient() { } public ThreadClient(String name) { this.name = name; } @Override public void run() { client(name); } public void client(String name) { Socket socket = null; BufferedWriter bufferedWriter = null; BufferedReader bufferedReader = null; try { //1.创建一个Socket对象 socket = new Socket("127.0.0.1", 8888); bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); //2.获取Socket的输入流,并使用缓冲区进行包装 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //添加内容:向服务器发送数据 bufferedWriter.write("这是" + name + "客户端向服务器端发送的数据 "); bufferedWriter.flush(); //3.接受服务器端发送的信息 String line = bufferedReader.readLine(); System.out.println(line); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); if (bufferedReader != null) bufferedReader.close(); if (bufferedWriter != null) bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
1.6 UDP通信
服务器端建立步骤:
1.创建socket服务,并监听端口
2.创建数据包,用来接收数据
3.用socket接收数据到数据包中
4.从数据包中取出数据
5.关闭资源
package com.jh.socketPackage; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class Server { public static void main(String[] args) { DatagramSocket datagramSocket = null; try { //1.创建服务器socket,并监听端口 datagramSocket = new DatagramSocket(8888); while (true) { byte[] bytes = new byte[1024]; //2.创建数据包,用来接收数据 DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length); //3.用socket接受数据到数据包中 datagramSocket.receive(datagramPacket); //4.读取数据 String s = new String(bytes, 0, bytes.length); System.out.println("消息是:" + s); if ("886".equals(s)) break; } } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { datagramSocket.close(); } } }
客户端建立步骤:
1.创建socket服务
2.创建数据包
3.将数据封装到数据包中,添加ip和端口以及数据
4.发送
5.关闭资源
package com.jh.socketPackage; import java.io.IOException; import java.net.*; import java.util.Scanner; public class Client { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); DatagramSocket datagramSocket = null; try { //1.创建客户端socket datagramSocket = new DatagramSocket(); while (true) { System.out.println("请输入要发送的信息:"); String line = scanner.nextLine(); //2.创建客户端发送数据包 byte[] bytes = line.getBytes(); //3.将数据封装到数据包中,添加ip和端口以及数据 DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 8888); //4.发送数据包 datagramSocket.send(datagramPacket); //结束发送循环 if ("886".equals(line)) break; } } catch (SocketException | UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { datagramSocket.close(); } } }
1.7 作业练习
1:编写一个基于TCP通信的程序,效果如图所示:
满足以下几点要求
A:服务器端具备多线程处理能力
B:客户端具备多线程发送能力
C:服务器端和客户端都具备从控制台接收输入的能力
C:服务器端和客户端都具备无限次数的双向通信能力
D:当服务器端或客户端发送”end”时通信结束
package project1; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ThreadServer { public static void main(String[] args) throws IOException { // 1:建立服务器端套接字,指定监听端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器端启动成功了!"); while (true) { Socket socket = serverSocket.accept(); // 开启线程处理这个socket Task task = new Task(socket); task.start(); } } }
package project1; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; public class Task extends Thread { private Socket socket; public Task() { } public Task(Socket socket) { this.socket = socket; } @Override public void run() { // 处理socket套接字 BufferedWriter bw = null; BufferedReader br = null; BufferedReader consoleIn = null; try { System.out.println("有客户端连接了!"); // 添加内容:从输入流中读取客户端发送过来的数据 br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 3:获取Socket的输出流,并使用缓冲流进行包装 bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 控制台输入流-->控制台向我发送的内容/控制台输入的内容 consoleIn = new BufferedReader(new InputStreamReader(System.in)); while (true) { // 从输入流中读取内容 String fromClien = br.readLine(); System.out.println("客户端:" + fromClien); // 4:向客户端发送反馈信息 System.out.print("服务器端:"); String toClient = consoleIn.readLine(); if (toClient.contains("end") || fromClien.contains("end")) { break; } bw.write(toClient + " "); bw.flush(); } } catch (IOException e) { e.printStackTrace(); } finally { // 5:关闭流及Socket连接 // a:关闭流 try { if (bw != null) bw.close(); } catch (IOException e) { e.printStackTrace(); } // b:关闭Socket try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
package project1; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import java.net.UnknownHostException; public class ThreadClient extends Thread { private String name; public ThreadClient(String name) { super(); this.name = name; } @Override public void run() { client(name); } public void client(String name) { Socket socket = null; BufferedReader br = null; BufferedWriter bw = null; BufferedReader consoleIn = null; try { // 1:创建一个Socket对象 socket = new Socket("127.0.0.1", 8888); // 添加内容:向服务发送一句话 bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 2:获取Socket的输入流,并使用缓冲流进行包装 br = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 控制台输入流-->控制台向我发送的内容/控制台输入的内容 consoleIn = new BufferedReader(new InputStreamReader(System.in)); while (true) { // 添加内容:向服务器端发送数据 System.out.print("客户端:"); String toServer = consoleIn.readLine(); if (toServer.contains("end")) { break; } bw.write(toServer + " "); bw.flush(); // 3接收服务器端发送的信息 String fromServer = br.readLine(); System.out.println("服务器端:" + fromServer); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 4:关闭流及Socket连接 // a:关闭流 try { if (br != null) br.close(); } catch (IOException e) { e.printStackTrace(); } // b:关闭Socket try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
package project1; public class TestClient { public static void main(String[] args) { new ThreadClient("1").start(); } }