Java是Internet上的语言,从语言层面提供了对网络应用程序的支持,便于开发网络应用程序
Java提供网络类库,将联网的底层细节隐藏,由JVM控制,提供统一的网络编程环境
网络中通信双方法的地址
IP地址:InetAddress——唯一标识Internet上的计算机(通信实体)
本地回环地址(HostAddresss)——127.0.0.1
主机名(HostName)——Localhost
IP地址分类:1、IPv4 & IPv6 2、公网地址 & 私有地址
Java中的IP类:1、通过get方法,获取该类的对象;2、通过域名(网址)获取类对象;
IP类的特殊对象:本地回路地址LocalHIst 127.0.0.1——本机IP地址
1、通过具体的IP地址,获取InetAddress类对象 InetAddress.getByName("192.168.10.14"); 2、通过域名获取InetAddress类对象 InetAddress.getByName("www.baidu.com"); 域名 → 本机Host → DNS服务器 …… → 实际网络服务器 3、特别的InetAddress类对象 localHost 127.0.0.1 本地回路地址 getLocalHost() 获取本机IP地址 4、InetAddress类常用的方法:获取本地ip getHostName() getHostAddress()
import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressTest { public static void main(String[] args) throws UnknownHostException { //1、通过get方法获取InetAddress类的对象 InetAddress inet1 = InetAddress.getByName("192.168.10.14"); //2、通过域名获取InetAddress类的对象 InetAddress inet2 = InetAddress.getByName("www.baidu.com"); //3、本地回路地址127.0.0.1 localHost 和本机ip System.out.println(InetAddress.getByName("localhost")); System.out.println(InetAddress.getLocalHost()); //4、常用方法 System.out.println(inet2.getHostName()); System.out.println(inet2.getHostAddress()); } }
端口号标识计算机正在运行的进程(程序)
不同的进程有不同的端口号,15位的整数:0-65535
端口分类:公认端口-0-1023——被预先定义的服务通信占用(HTTP80、FTP21、TeInet23)
注册端口:1024-49151——分配给用户进程或程序(Tomcat8080、MySQL3306、Oracle1521)
动态/私有端口:49152-65535
端口和IP地址结合得到网络套接字——Socket【程序(进程)之间定位实现】
传输层协议中的两个重要协议:
TCP/IP协议簇以【TCP协议】【IP协议:网络互联协议】得名——具有不同功能,相互关联的协议组
IP协议Internet Protocol:是网络层的主要协议,支持网间互联的数据通信
TCP/IP协议模型,从实际的角度出发,形成了高效的四层体系结构(物理链路层、IP层、传输层、应用层)
TCP:
UDP:
TCP建立连接:三次握手;释放连接:四次你挥手
客户端和服务端,都可以挥手(实际一般都是客户端发起挥手)
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * @ClassName:TCPTest1 * @Description: TODO * @Author ChenS * @create 2021-06-27-4:40 PM * @Version 1.0 */ //程序运行如果端口报错,可临时切换端口号解决 public class TCPTest1 { public static void main(String[] args) { //准备两个线程分别运行客户端和服务器端 //先启动服务端 new Thread(new Runnable() { @Override public void run() { try { server1.receiveMessage(7799); } catch (IOException e) { e.printStackTrace(); } } }).start(); //再启动客户端 new Thread(new Runnable() { @Override public void run() { try { client1.sendMessage("这一条信息来自客户端", "127.0.0.1", 7799); } catch (IOException e) { e.printStackTrace(); } } }).start(); } } class client1{ public static void sendMessage(String meg,String ip,int port) throws IOException { //创建InetAddress对象 InetAddress inet1 = InetAddress.getByName(ip); //创建用于发送的Socket Socket socket = new Socket(inet1, port); //调用方法,获取需要输出的流 OutputStream outputStream = socket.getOutputStream(); //向输出流中添加信息 outputStream.write(meg.getBytes()); //关闭资源 socket.close(); outputStream.close(); } } class server1{ public static void receiveMessage(int port) throws IOException { //创建serverSocket ServerSocket serverSocket = new ServerSocket(port); //调用方法,获取客户端传输的socket Socket acceptedSocket = serverSocket.accept(); //调用方法,获取socket中的流 InputStream inputStream = acceptedSocket.getInputStream(); //为避免传输的文字乱码,使用字节数组输出流接受信息 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //处理数据 byte[] bytes = new byte[5]; int len; while ((len = inputStream.read(bytes)) != -1){ byteArrayOutputStream.write(bytes,0,len); } System.out.println(byteArrayOutputStream.toString()); System.out.println("接收到了来自:" + acceptedSocket.getLocalAddress() + "的信息"); //关闭资源 serverSocket.close(); acceptedSocket.close(); inputStream.close(); byteArrayOutputStream.close(); } }
import java.io.*; import java.net.*; /** * @ClassName:TCPTest2 * @Description: TODO * @Author ChenS * @create 2021-06-27-5:43 PM * @Version 1.0 */ //报异常未找到文件,可切换目的文件地址解决 public class TCPTest2 { public static void main(String[] args) { String srcFilePath = "D:\\ LOL\\如何自学Java:入门与编程技能训练.pptx"; String desFilePath = "D:\\AA\\如何自学Java:入门与编程技能训练.pptx"; String ip = "127.0.0.1"; int port = 8991; new Thread(new Runnable() { @Override public void run() { try { Server2.receiveFile(desFilePath, port ); } catch (IOException e) { e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { Client2.sendFile(srcFilePath, ip, port); } catch (IOException e) { e.printStackTrace(); } } }).start(); } } class Client2{ public static void sendFile(String srcFilePath,String ip,int port) throws IOException { //1、创建Socket对象 Socket socket = new Socket(InetAddress.getByName(ip), port); //2、调用方法,获取输出流 OutputStream outputStream = socket.getOutputStream(); //3、准备File对象 和输入流 FileInputStream fileInputStream = new FileInputStream(new File(srcFilePath)); //4、读写数据操作 byte[] bytes = new byte[1024]; int len; while ((len = fileInputStream.read(bytes)) != -1){ outputStream.write(bytes,0,len); } //关闭资源 fileInputStream.close(); outputStream.close(); socket.close(); } } class Server2{ public static void receiveFile(String desFilePath,int port) throws IOException { //1、创建服务端Socket ServerSocket serverSocket = new ServerSocket(port); //2、调用方法,获取客户端Socket Socket accept = serverSocket.accept(); //3、调用方法,获取输入流 InputStream inputStream = accept.getInputStream(); //4、准备File 和 输出流 FileOutputStream fileOutputStream = new FileOutputStream(new File(desFilePath)); //5、操作文件 byte[] bytes = new byte[1024]; int len; while ((len = inputStream.read(bytes)) != -1){ fileOutputStream.write(bytes,0 ,len); } System.out.println("接收完毕"); //6、关闭资源 serverSocket.close(); accept.close(); inputStream.close(); fileOutputStream.close(); } }
注意建立的连接Socket只有一个,因此在使用Socket获取输出流或者输入流,操作结束后,应该关闭流对Socket的占用(此时是阻塞式的,需要手动解除Socket占用)
socketFromClient.shutdownOutput();//关闭Socket中的输出流
socketFromClient.shutdownInput();//关闭Socket中的输入流
import java.io.*; import java.net.*; public class TCPTest2 { public static void main(String[] args) { String srcFilePath = "D:\\ LOL\\如何自学Java:入门与编程技能训练.pptx"; String desFilePath = "D:\\AA\\如何自学Java:入门与编程技能训练.pptx"; String ip = "127.0.0.1"; int port = 8991; new Thread(new Runnable() { @Override public void run() { try { Server2.receiveFile(desFilePath, port ); } catch (IOException e) { e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { Client2.sendFile(srcFilePath, ip, port); } catch (IOException e) { e.printStackTrace(); } } }).start(); } } class Client2{ public static void sendFile(String srcFilePath,String ip,int port) throws IOException { //1、创建Socket对象 Socket socketFromClient = new Socket(InetAddress.getByName(ip), port); //2、调用方法,获取输出流 OutputStream outputStream = socketFromClient.getOutputStream(); //3、准备File对象 和输入流 FileInputStream fileInputStream = new FileInputStream(new File(srcFilePath)); //4、读写数据操作 byte[] bytes = new byte[1024]; int len; while ((len = fileInputStream.read(bytes)) != -1){ outputStream.write(bytes,0,len); } socketFromClient.shutdownOutput();//关闭Socket中的输出流 //接受来自服务端确认信息 InputStream inputStream = socketFromClient.getInputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] bytes1 = new byte[24]; int len1; while ((len1 = inputStream.read(bytes1)) != -1){ byteArrayOutputStream.write(bytes1,0,len1); } System.out.println(byteArrayOutputStream.toString()); //关闭资源 fileInputStream.close(); outputStream.close(); socketFromClient.close(); inputStream.close(); byteArrayOutputStream.close(); } } class Server2{ public static void receiveFile(String desFilePath,int port) throws IOException { //1、创建服务端Socket ServerSocket serverSocket = new ServerSocket(port); //2、调用方法,获取客户端Socket Socket socketFromClient = serverSocket.accept(); //3、调用方法,获取输入流 InputStream inputStream = socketFromClient.getInputStream(); //4、准备File 和 输出流 FileOutputStream fileOutputStream = new FileOutputStream(new File(desFilePath)); //5、操作文件 byte[] bytes = new byte[1024]; int len; while ((len = inputStream.read(bytes)) != -1){ fileOutputStream.write(bytes,0 ,len); } socketFromClient.shutdownInput();//关闭Socket输入流 System.out.println("接收完毕(来自服务端)"); //使用得到的客户端Socket的输出流,并写入字符串 OutputStream outputStream = socketFromClient.getOutputStream(); outputStream.write("文件复制完成(来自服务端)".getBytes()); //6、关闭资源 serverSocket.close(); socketFromClient.close(); inputStream.close(); fileOutputStream.close(); outputStream.close(); } }
练习1:服务端,读取本地图片,发送给客户端
练习2:客户端发送文本给服务端,服务端返回给客户端全部转化为大写的文本
1、安装启动Tomcat服务器、启动服务
2、创建服务器中资源文件
3、通过浏览器,直接访问资源文件LocalHost:8080\xxx
package Day12; import java.io.IOException; import java.net.*; /** * @ClassName:UDPTest * @Description: TODO * @Author ChenS * @create 2021-06-27-7:35 PM * @Version 1.0 */ public class UDPTest { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { try { Receiver.receive( 8080); } catch (IOException e) { e.printStackTrace(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { Sender.send("String from sender","127.0.0.1",8080); } catch (IOException e) { e.printStackTrace(); } } }).start(); } } class Sender { public static void send(String str,String senderIP,int port) throws IOException { //建立UDPSocket DatagramSocket datagramSocket = new DatagramSocket(); //封装数据包 DatagramPacket datagramPacket = new DatagramPacket(str.getBytes(), 0, str.length(),InetAddress.getByName(senderIP),port); //发送数据 datagramSocket.send(datagramPacket); //关闭资源 datagramSocket.close(); } } class Receiver{ public static void receive(int port) throws IOException { //建立UDPSocket DatagramSocket datagramSocket = new DatagramSocket(port); //建立接收数据包 byte[] bytes = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length); //接收数据 datagramSocket.receive(datagramPacket); //使用数据——数据实际上存储到准备的字节数据组中 System.out.println(new String(bytes)); //关闭资源 datagramSocket.close(); } }
import java.net.MalformedURLException; import java.net.URL; public class URLTest { public static void main(String[] args) { //获取URL对象 URL url = null; try { url = new URL("https://blog.csdn.net/qq_43810938?spm=1001.2014.3001.5343"); } catch (MalformedURLException e) { e.printStackTrace(); } //URL方法 //获取协议名 System.out.println(url.getProtocol()); //获取主机名 System.out.println(url.getHost()); //获取端口号 System.out.println(url.getPort()); //获取文件名 System.out.println(url.getFile()); //获取URL查询名 System.out.println(url.getQuery()); } }
import javax.net.ssl.HttpsURLConnection; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; /** * @ClassName:URLTest * @Description: TODO * @Author ChenS * @create 2021-06-27-8:12 PM * @Version 1.0 */ public class URLTest { public static void main(String[] args) throws IOException { //获取URL对象 URL url = new URL("https://tsundora.com/image/2016/09/code_geass_600.jpg"); //创建这个ulr的连接对象 HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); //连接 urlConnection.connect(); //获取输入流,创建输出流 InputStream inputStream = urlConnection.getInputStream(); FileOutputStream fileOutputStream = new FileOutputStream(new File("code_geass_600.jpg")); byte[] bytes = new byte[1024]; int len; while ((len = inputStream.read(bytes)) != -1){ fileOutputStream.write(bytes, 0, len); } //关闭资源 inputStream.close(); fileOutputStream.close(); urlConnection.disconnect(); } }