- 概念:两台设备之间通过网络实现数据运输
- 网络通信:将数据通过网络从一台设备传输到另一台设备
- java.net包下提供了一系列的类或接口,供程序员使用,完成网络通信
- 网络:两台或多台设备通过一定物理设备连接起来构成了网络
- 根据网络的覆盖范围不同,对网络进行分类:
- 局域网:覆盖范围最小,仅仅覆盖一个教室或一个机房
- 城域网:覆盖范围较大,可以覆盖一个城市
- 广域网:覆盖范围最大,可以覆盖全国,甚至全球,万维网是广域网的代表。
- ip地址
- IPV4和IPV6的区别,IPV4的地址分类的范围,8位二进制表示范围(0-255)
- 域名,端口号
- 网络通信协议
- TCP和UDP
- InetAddress类
-
package com.jshedu.api; import java.net.InetAddress; import java.net.UnknownHostException; /** * @author 韩顺平 * @version 1.0 * 演示InetAddress 类的使用 */ public class API_ { public static void main(String[] args) throws UnknownHostException { //1. 获取本机的InetAddress 对象 InetAddress localHost = InetAddress.getLocalHost(); System.out.println(localHost);//DESKTOP-S4MP84S/192.168.12.1 //2. 根据指定主机名 获取 InetAddress对象 InetAddress host1 = InetAddress.getByName("DESKTOP-DFGSCKR"); System.out.println("host1=" + host1);//DESKTOP-S4MP84S/192.168.12.1 //3. 根据域名返回 InetAddress对象, 比如 www.baidu.com 对应 InetAddress host2 = InetAddress.getByName("www.baidu.com"); System.out.println("host2=" + host2);//www.baidu.com / 110.242.68.4 //4. 通过 InetAddress 对象,获取对应的地址 String hostAddress = host2.getHostAddress();//IP 110.242.68.4 System.out.println("host2 对应的ip = " + hostAddress);//110.242.68.4 //5. 通过 InetAddress 对象,获取对应的主机名/或者的域名 String hostName = host2.getHostName(); System.out.println("host2对应的主机名/域名=" + hostName); // www.baidu.com } }
InetAddress的方法
-
-
Socket
- TCP字节流编程
- 服务端设置一个等待连接的端口,用accept()方法接收客户端连接,客户端用Socket构造器提供ip地址和端口号去连接服务端。然后客户端通过getOutputStream()生成对象,该对象调用write()方法写入数据到数据通道。服务端通过getInputStream()生成对象,调用read()方法读取客户端写入到数据通道的数据。
-
package com.jshedu.socket; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; /** * @author 韩顺平 * @version 1.0 * 服务端 */ public class SocketTCP01Server { public static void main(String[] args) throws IOException { //思路 //1. 在本机 的9999端口监听, 等待连接 // 细节: 要求在本机没有其它服务在监听9999 // 细节:这个 ServerSocket 可以通过 accept() 返回多个Socket[多个客户端连接服务器的并发] ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服务端,在9999端口监听,等待连接.."); //2. 当没有客户端连接9999端口时,程序会 阻塞, 等待连接 // 如果有客户端连接,则会返回Socket对象,程序继续 Socket socket = serverSocket.accept(); System.out.println("服务端 socket =" + socket.getClass()); // //3. 通过socket.getInputStream() 读取客户端写入到数据通道的数据, 显示 InputStream inputStream = socket.getInputStream(); //4. IO读取 byte[] buf = new byte[1024]; int readLen = 0; while ((readLen = inputStream.read(buf)) != -1) { System.out.println(new String(buf, 0, readLen));//根据读取到的实际长度,显示内容. } //5.关闭流和socket inputStream.close(); socket.close(); serverSocket.close();//关闭 } }
-
package com.jshedu.socket; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * @author 韩顺平 * @version 1.0 * 客户端,发送 "hello, server" 给服务端 */ public class SocketTCP01Client { public static void main(String[] args) throws IOException { //思路 //1. 连接服务端 (ip , 端口) //解读: 连接本机的 9999端口, 如果连接成功,返回Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); System.out.println("客户端 socket返回=" + socket.getClass()); //2. 连接上后,生成Socket, 通过socket.getOutputStream() // 得到 和 socket对象关联的输出流对象 OutputStream outputStream = socket.getOutputStream(); //3. 通过输出流,写入数据到 数据通道 outputStream.write("hello, server".getBytes()); //4. 关闭流对象和socket, 必须关闭 outputStream.close(); socket.close(); System.out.println("客户端退出....."); } }
注意要关闭流对象和socket
-
双向传输信息
-
package com.jshedu.api; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * @author Mr.jia * @version 1.0 */ @SuppressWarnings({"all"}) public class SocketServe { public static void main(String[] args) throws IOException { //设置端口号返回ServerSocket对象 ServerSocket serverSocket = new ServerSocket(9999); //使用accept()方法接收 System.out.println("服务端,在9999端口监听,等待连接..."); Socket accept = serverSocket.accept(); //读取数据通道的数据然后输出在显示台 InputStream inputStream = accept.getInputStream(); //使用IO流输出 byte[] bytes = new byte[1024]; int readLine = 0; while((readLine=inputStream.read(bytes))!=-1){ System.out.println(new String(bytes,0,readLine)); } //写入数据到数据通道 OutputStream outputStream = accept.getOutputStream(); outputStream.write("hello,client".getBytes()); //结束标记 accept.shutdownInput(); //关闭流 inputStream.close(); outputStream.close(); accept.close(); serverSocket.close(); } }
package com.jshedu.api; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * @author Mr.jia * @version 1.0 */ @SuppressWarnings({"all"}) public class SocketClient { public static void main(String[] args) throws IOException { //要连接的端口号 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); //得到输入流对象 OutputStream outputStream = socket.getOutputStream(); //写入数据 outputStream.write("hello server".getBytes()); socket.shutdownOutput(); //读取数据 InputStream inputStream = socket.getInputStream(); //使用IO流输出 byte[] bytes = new byte[1024]; int readLine = 0; while((readLine=inputStream.read(bytes))!=-1){ System.out.println(new String(bytes,0,readLine)); } //关闭流 outputStream.close(); socket.close(); inputStream.close(); System.out.println("客户端退出"); } }
-
-
使用字符流
package com.jshedu.api; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * @author Mr.jia * @version 1.0 */ @SuppressWarnings({"all"}) public class SocketServe { public static void main(String[] args) throws IOException { //设置端口号返回ServerSocket对象 ServerSocket serverSocket = new ServerSocket(9999); //使用accept()方法接收 System.out.println("服务端,在9999端口监听,等待连接..."); Socket accept = serverSocket.accept(); //读取数据通道的数据然后输出在显示台 InputStream inputStream = accept.getInputStream(); //使用IO流输出,使用字符流 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); System.out.println(s); //写入数据到数据通道 OutputStream outputStream = accept.getOutputStream(); //使用字符输出流的方式回复信息 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write("hello client 字符流"); //结束标记 bufferedWriter.newLine();//插入一个换行符,表示回复内容的结束 bufferedWriter.flush();//注意需要手动的flush //关闭流 bufferedReader.close(); bufferedWriter.close(); accept.close(); serverSocket.close(); } }
package com.jshedu.api; import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * @author Mr.jia * @version 1.0 */ @SuppressWarnings({"all"}) public class SocketClient { public static void main(String[] args) throws IOException { //要连接的端口号 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); //得到输入流对象 OutputStream outputStream = socket.getOutputStream(); //写入数据,使用字符流 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write("hello server 字符流"); bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束 //注意要求对方使用readLine()!!! bufferedWriter.flush();//如果使用的字符流,需要手动刷新,否则数据不会写入数据通道 socket.shutdownOutput(); //读取数据 InputStream inputStream = socket.getInputStream(); //使用IO流输出 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); System.out.println(s); //关闭流 bufferedReader.close(); socket.close(); bufferedWriter.close(); System.out.println("客户端退出"); } }
注意字节流转换成字符流,结束标记,flush
-
传输图片/音乐
-
package com.hspedu.upload; import java.io.*; import java.net.ServerSocket; import java.net.Socket; /** * @author 韩顺平 * @version 1.0 * 文件上传的服务端 */ public class TCPFileUploadServer { public static void main(String[] args) throws Exception { //1. 服务端在本机监听8888端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端在8888端口监听...."); //2. 等待连接 Socket socket = serverSocket.accept(); //3. 读取客户端发送的数据 // 通过Socket得到输入流 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] bytes = StreamUtils.streamToByteArray(bis); //4. 将得到 bytes 数组,写入到指定的路径,就得到一个文件了 String destFilePath = "src\\abc.mp4"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath)); bos.write(bytes); bos.close(); // 向客户端回复 "收到图片" // 通过socket 获取到输出流(字符) BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write("收到图片"); writer.flush();//把内容刷新到数据通道 socket.shutdownOutput();//设置写入结束标记 //关闭其他资源 writer.close(); bis.close(); socket.close(); serverSocket.close(); } }
-
package com.hspedu.upload; import java.io.*; import java.net.InetAddress; import java.net.Socket; /** * @author 韩顺平 * @version 1.0 * 文件上传的客户端 */ public class TCPFileUploadClient { public static void main(String[] args) throws Exception { //客户端连接服务端 8888,得到Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 8888); //创建读取磁盘文件的输入流 //String filePath = "e:\\qie.png"; String filePath = "e:\\abc.mp4"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath)); //bytes 就是filePath对应的字节数组 byte[] bytes = StreamUtils.streamToByteArray(bis); //通过socket获取到输出流, 将bytes数据发送给服务端 BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道 bis.close(); socket.shutdownOutput();//设置写入数据的结束标记 //=====接收从服务端回复的消息===== InputStream inputStream = socket.getInputStream(); //使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串 String s = StreamUtils.streamToString(inputStream); System.out.println(s); //关闭相关的流 inputStream.close(); bos.close(); socket.close(); } }
-
package com.hspedu.upload; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; /** * 此类用于演示关于流的读写方法 * */ public class StreamUtils { /** * 功能:将输入流转换成byte[] * @param is * @return * @throws Exception */ public static byte[] streamToByteArray(InputStream is) throws Exception{ ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象 byte[] b = new byte[1024]; int len; while((len=is.read(b))!=-1){ bos.write(b, 0, len); } byte[] array = bos.toByteArray(); bos.close(); return array; } /** * 功能:将InputStream转换成String * @param is * @return * @throws Exception */ public static String streamToString(InputStream is) throws Exception{ BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder builder= new StringBuilder(); String line; while((line=reader.readLine())!=null){ //当读取到 null时,就表示结束 builder.append(line+"\r\n"); } return builder.toString(); } }
-
当客户端连接服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口号TCP/IP来分配,是不确定的,随机的