ipv4地址分类
TCP/IP(Transmission Control Protocol/Internet Protocol)的简写,中文译名为:传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议,Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的.
TCP协议:传输控制协议
案例:
/** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-16:43 * @Version 演示InetAddress类的使用 */ //主机名等价域名对应一个ip(地址) public class API_ { public static void main(String[] args) throws UnknownHostException { //1. 获取本机的InetAddress 对象 InetAddress localHost = InetAddress.getLocalHost(); System.out.println("localHost = " + localHost);//主机名/ip //2. 根据指定 主机名 获取 InetAddress对象 InetAddress host1 = InetAddress.getByName("WIN-I0Q1644D4PA"); System.out.println("host1 = " + host1);//主机名/ip //3. 根据 域名 获取InetAddress对象 //亦可根据ip获取InetAddress对象 InetAddress host2 = InetAddress.getByName("www.baidu.com"); System.out.println("host2 = " + host2); //4. 通过 InetAddress 对象,获取对应的地址 String address = host2.getHostAddress(); System.out.println("address = " + address); //5. 通过 InetAddress 对象,获取对应的主机名/或者的域名 String name = host2.getHostName(); System.out.println("name = " + name); } }
/** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:25 * @Version * 服务端 */ public class Server { public static void main(String[] args) throws IOException { //在(默认)本机的指定端口建立服务端插座 //注意:serverSocket监听9999的前提是没有其他服务在监听9999 ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服务端,在9999端口监听,并等待连接.."); //等待连接插入-->若没有连接,程序阻塞-->若连接成功,返回Socket对象,程序继续 //注意:该方法可返回多个Socket对象->多个客户端连接服务器的并发 Socket socket = serverSocket.accept(); //net包下Socket类型 System.out.println("服务端 socket="+socket.getClass()); //通过网络连接构造输入流:读取 InputStream inputStream = socket.getInputStream(); byte[] buf = new byte[1024]; int length; while ((length = inputStream.read(buf)) != -1) { System.out.println(new String(buf, 0, length)); } //关闭流,连接,端口插座(插孔有限)以节约资源 inputStream.close(); socket.close(); serverSocket.close(); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:25 * @Version * 客户端,发送 "hello, server" 给服务端 */ public class Client { public static void main(String[] args) throws IOException { //客户端连接到服务端(本机的9999端口)的插座-->若连接成功,返回Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); //与服务端的连接类型一致 System.out.println("客户端socket="+socket.getClass()); //通过网络连接构造输出流:写入 OutputStream outputStream = socket.getOutputStream(); outputStream.write("hello,sever".getBytes()); //关闭流,连接 outputStream.close(); socket.close(); System.out.println("客户端退出..."); } }
1.编写一个服务端,和一个客户端
2.服务器端在9999端口监听
3.客户端连接到服务端,发送”hello, serer",并接收服务器端回发的 “heilo,client”,再退出
4.服务器端接收到客户端发送的信息,输出,并发送”hello, client",再退出
/** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:57 * @Version * 服务端:接收客户端发送的消息-->并发送"hello,client" */ public class Server { @SuppressWarnings({"all"}) public static void main(String[] args) throws IOException { //在(默认)本机的指定端口建立服务端插座 //注意:serverSocket监听9999的前提是没有其他服务在监听9999 ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服务端,在9999端口监听,并等待连接.."); //等待连接插入-->若没有连接,程序阻塞-->若连接成功,返回Socket对象,程序继续 //注意:该方法可返回多个Socket对象->多个客户端连接服务器的并发 Socket socket = serverSocket.accept(); //net包下Socket类型 System.out.println("服务端 socket="+socket.getClass()+"已连接"); //通过网络连接构造输入流:读取 InputStream inputStream = socket.getInputStream(); byte[] buf = new byte[1024]; int length; while ((length = inputStream.read(buf)) != -1) { System.out.println(new String(buf, 0, length)); } //读取后的 写入到数据通道 OutputStream outputStream = socket.getOutputStream(); outputStream.write("hello,client".getBytes()); //设置(输出)结束标记 socket.shutdownOutput();//若写入后没有再传输可以不设置标记 //关闭流,连接,端口插座(插孔有限)以节约资源 outputStream.close(); inputStream.close(); socket.close(); serverSocket.close(); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:56 * @Version * 客户端:连接服务端-->发送"hello,server"-->接收服务端回发的"hello,client"-->退出 */ public class Client { @SuppressWarnings({"all"}) public static void main(String[] args) throws IOException { //客户端连接到服务端(本机的9999端口)的插座-->若连接成功,返回Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); //与服务端的连接类型一致 System.out.println("客户端socket="+socket.getClass()+"已连接"); //通过网络连接构造输出流:写入 OutputStream outputStream = socket.getOutputStream(); outputStream.write("hello,sever".getBytes()); //设置(输出)结束标记(先写后读不可省略,否则两端都阻塞在数据的传输上) // socket.shutdownOutput(); //写入后的 读取数据 InputStream inputStream = socket.getInputStream(); byte[] buf = new byte[1024]; int length; while ((length = inputStream.read(buf)) != -1) { System.out.println(new String(buf, 0, length)); } //关闭流,连接 inputStream.close(); outputStream.close(); socket.close(); System.out.println("客户端退出..."); } }
/** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:57 * @Version 字符流方式 * 服务端:接收客户端发送的消息-->并发送"hello,client" */ public class Server { @SuppressWarnings({"all"}) public static void main(String[] args) throws IOException { //在(默认)本机的指定端口建立服务端插座 //注意:serverSocket监听9999的前提是没有其他服务在监听9999 ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服务端,在9999端口监听,并等待连接.."); //等待连接插入-->若没有连接,程序阻塞-->若连接成功,返回Socket对象,程序继续 //注意:该方法可返回多个Socket对象->多个客户端连接服务器的并发 Socket socket = serverSocket.accept(); //net包下Socket类型 System.out.println("服务端 socket="+socket.getClass()+"已连接"); //通过网络连接构造输入流:读取 InputStream inputStream = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); System.out.println(br.readLine()); //读取后的 写入到数据通道 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream)); bw.write("hello,client 字符流"); //设置(输出)结束标记 // bw.newLine();//若写入后没有再传输可以不设置标记 //关闭流,连接,端口插座(插孔有限)以节约资源 bw.close();//写入 br.close(); socket.close(); serverSocket.close(); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-17:56 * @Version 字符流方式 * 客户端:连接服务端-->发送"hello,server"-->接收服务端回发的"hello,client"-->退出 */ public class Client { @SuppressWarnings({"all"}) public static void main(String[] args) throws IOException { //客户端连接到服务端(本机的9999端口)的插座-->若连接成功,返回Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); //与服务端的连接类型一致 System.out.println("客户端socket="+socket.getClass()+"已连接"); //通过网络连接构造输出流:写入 OutputStream outputStream = socket.getOutputStream(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream)); bw.write("hello,server 字符流"); //设置(输出)结束标记(先写后读不可省略,否则两端都阻塞在数据的传输上) bw.newLine();//对应的另一端必须使用readLine!!! bw.flush();//刷新以写入 //写入后的 读取数据 InputStream inputStream = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); System.out.println(br.readLine()); //关闭流,连接 br.close(); bw.close(); socket.close(); System.out.println("客户端退出..."); } }
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(); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-19:58 * @Version 服务端 * 接收客户端发送的文件-->保存到系统文件目录下-->发送"收到图片"后退出 */ public class Server { public static void main(String[] args) throws Exception { //创建字节输出流-->上传到本地 String filePath = "chapter21\\src\\Copy.wmv"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); //服务端监听本机端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端,监听8888端口,等待连接..."); //等待连接 Socket socket = serverSocket.accept(); //连接后创建数据通道的输入流/输出流 InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); /*byte[] buf = new byte[1024]; int length; //从数据通道的输入流读取到图片数据 while ((length = inputStream.read(buf)) != -1) { //通过字节输出流将数据写入到指定目录下的文件 bos.write(buf,0,length); }*/ //不使用缓冲数组的先读后写(简化了循环读写) byte[] bytes = StreamUtils.streamToByteArray(inputStream); bos.write(bytes); //从数据通道的输出流写入文本数据 outputStream.write("收到图片".getBytes()); //关闭资源 outputStream.close(); inputStream.close(); bos.close(); socket.close(); serverSocket.close(); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-05-19:58 * @Version 客户端 * 连接到服务端-->发送磁盘里的文件-->接收到"收到图片"后退出 */ public class Client { public static void main(String[] args) throws Exception { //创建字节输入流-->从磁盘读取到内存 String filePath = "f:\\io\\bufferedCopy.wmv"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath)); //连接到服务端 Socket socket = new Socket(InetAddress.getLocalHost(), 8888); //创建数据通道的输出流/输入流 OutputStream outputStream = socket.getOutputStream(); InputStream inputStream = socket.getInputStream(); /*byte[] buf = new byte[1024]; int length; //通过字节输入流从磁盘读取到图片数据 while ((length = bis.read(buf)) != -1) { //通过数据通道的输出流写入图片数据 outputStream.write(buf,0,length); }*/ //简化版先读后写 byte[] bytes = StreamUtils.streamToByteArray(bis); outputStream.write(bytes); //设置传输结束标记 socket.shutdownOutput(); /*byte[] bytes = new byte[1024]; int len; //通过数据通道的输入流读取文本数据 while ((len = inputStream.read(bytes))!=-1) { System.out.println(new String(bytes,0,len)); }*/ //简化版循环读取打印 String string = StreamUtils.streamToString(inputStream); System.out.println(string); //关闭资源 inputStream.close(); outputStream.close(); bis.close(); socket.close(); } }
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(); } } public class Server { public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(9999); System.out.println("服务端,监听9999端口,等待连接..."); Socket socket = serverSocket.accept(); //接收文件名 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String musicName = br.readLine(); System.out.println("客户端点歌:"+musicName); String srcPath = ""; if (musicName.equals("高山流水")) { srcPath = "chapter21\\src\\高山流水.mp3"; } else { srcPath="chapter21\\src\\无名.mp3"; } //提取文件数据到数组 FileInputStream fileInputStream = new FileInputStream(srcPath); byte[] data = StreamUtils.streamToByteArray(fileInputStream); BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); bos.write(data); bos.close(); fileInputStream.close(); br.close(); socket.close(); serverSocket.close(); } } public class Client { public static void main(String[] args) throws Exception { Socket socket = new Socket(InetAddress.getLocalHost(), 9999); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); Scanner sc = new Scanner(System.in); System.out.println("请输入下载的音乐名"); String music = sc.next(); bw.write(music); bw.newLine(); bw.flush(); InputStream inputStream = socket.getInputStream(); byte[] data = StreamUtils.streamToByteArray(inputStream); String destPath = ""; if (music.equals("高山流水")) { destPath = "f:\\io\\高山流水.mp3"; } else { destPath = "f:\\io\\zxk.mp3"; } FileOutputStream fos = new FileOutputStream(destPath); fos.write(data); fos.close(); inputStream.close(); bw.close(); socket.close(); System.out.println("客户端退出"); } }
补充:
netstat -anb指令:
查看监听端口的应用:
必须在管理员身份下运行控制台输入指令
/** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-06-0:53 * @Version 接收端A */ public class UDPReceiverA { public static void main(String[] args) throws IOException { //创建DatagramSocket对象-->在指定端口接收 DatagramSocket socket = new DatagramSocket(9999); //创建DatagramPacket对象-->准备接收数据报 byte[] bytes = new byte[1024];//接收数组 DatagramPacket packet = new DatagramPacket(bytes, bytes.length); System.out.println("端口A,监听9999端口,等待接收..."); //调用 接收方法, 将通过网络传输的 DatagramPacket 对象,填充到 packet对象 socket.receive(packet); //拆包显示 int length = packet.getLength(); byte[] data = packet.getData(); String s = new String(data, 0, length); System.out.println(s); //创建待发送数据报,并指明接收端的地址和端口 byte[] buf = "好的明天见".getBytes(); packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.200.1"), 9998); socket.send(packet); socket.close(); System.out.println("A端退出"); } } /** * @ClassName * @Description * @Author zxk * @DateTime 2022-02-06-0:53 * @Version 发送端B */ public class UDPSenderB { public static void main(String[] args) throws IOException { //创建DatagramSocket对象-->在指定端口接收 DatagramSocket socket = new DatagramSocket(9998); //待发送数据封装到数据报 byte[] data = "hello,明天吃火锅~".getBytes(); //待发报中指明接收地址和端口 DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.200.1"), 9999); socket.send(packet); //创建数据报准备接收 byte[] bytes = new byte[1024]; packet = new DatagramPacket(bytes, bytes.length); System.out.println("端口B,监听9998端口,等待接收..."); //调用接收方法填充数据报 socket.receive(packet); //拆包显示 int length = packet.getLength();//实际接收的数据字节长度 byte[] buf = packet.getData();//接收到的数据 String s = new String(buf, 0, length); System.out.println(s); socket.close(); System.out.println("B端退出"); } }