一、网络的相关概念
1 网络通信
2 网络
3 ip 地址
4.ipv4 地址分类
5.域名
6 网络通信协议
7.网络通信协议
8.TCP 和 UDP
二、InetAddress 类 &Socket
1 相关方法
package com.hspedu.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 {//获取本机的INetAddress对象InetAddress inetAddress =InetAddress.getLocalHost();System.out.println(inetAddress);//根据指定的主机名获取 INetAddress对象InetAddress host = InetAddress.getByName("Admin-Lin-Ran");System.out.println(host);//根据一个域名返回InetAddress对象InetAddress host2 =InetAddress.getByName("www.baidu.com");System.out.println(host2);//通过InetAdress对象,获取对应的地址String hostAddress =host2.getHostAddress();//System.out.println(hostAddress);//通过InetAdress对象,获取对应的主机名或者域名String hostName =host2.getHostName();//System.out.println(hostName);}
}
2 Socket
2.1 基本介绍
2.2 示意图
三、TCP 网络通信编程
1.基本介绍
2 应用案例 1(使用字节流)
【SreeverSocket对应多个socket】
【Sever】
package com.hspedu.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.关闭流和 socketinputStream.close();socket.close();serverSocket.close();}
}
【Client】
package com.hspedu.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());//关闭流对象和socketoutputStream.close();socket.close();}
}
3.应用案例 2(使用字节流)
【服务器端】
package com.hspedu.socket;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;/*** @author 林然* @version 1.0* 服务端*/
public class SocketTCP02Server {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));//根据读取到的实际长度,显示内容}// 设置结束标记socket.shutdownInput();OutputStream outputStream = socket.getOutputStream();String str ="hello,client";outputStream.write(str.getBytes());// 设置结束标记socket.shutdownOutput();//5.关闭流和 socketoutputStream.close();inputStream.close();socket.close();serverSocket.close();}
}
【客户端】
package com.hspedu.socket;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 林然* @version 1.0* 客户端,发送 "hello, server" 给服务端*/
public class SocketTCP02Client {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());// 设置结束标记socket.shutdownOutput();InputStream inputStream = socket.getInputStream();byte [] buf =new byte[1024];int readl=0;while ((readl=inputStream.read(buf))!=-1){System.out.println(new String(buf,0,readl));}// 设置结束标记socket.shutdownInput();//关闭流对象和socketinputStream.close();outputStream.close();socket.close();}
}
4.应用案例 3(使用字符流)
【Sever】
package com.hspedu.socket;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*** @author 林然* @version 1.0*/
public class SocketTCP03Server {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();BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(inputStream));//4. IO 读取,使用字符流String str1=bufferedReader.readLine();System.out.println(str1);// 设置结束标记OutputStream outputStream = socket.getOutputStream();BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(outputStream));String str ="hello,client";bufferedWriter.write(str);// 设置结束标记bufferedWriter.newLine();bufferedWriter.flush();//5.关闭流和 socketbufferedReader.close();bufferedWriter.close();socket.close();serverSocket.close();}
}
【client】
package com.hspedu.socket;import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;/*** @author 林然* @version 1.0*/
public class SocketTCP03Client {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. 通过输出流,写入数据到 数据通道,要求使用字符流BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));bufferedWriter.write("hello,server 字符流");bufferedWriter.newLine();//插入一个换行符,表示输入结束,注意要求对方用realLine()!!!//如果使用的字符流,需要手动刷新,否则数据不会写入数据通道bufferedWriter.flush();InputStream inputStream = socket.getInputStream();BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));String str =bufferedReader.readLine();System.out.println(str);// 设置结束标记//关闭流对象和socketbufferedReader.close();bufferedWriter.close();socket.close();}
}
5.应用案例 4【传送文件】
【StreamUtils】
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[], 即可以把文件的内容读入到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);//把读取到的数据,写入bos }byte[] array = bos.toByteArray();//然后将bos 转成字节数组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){builder.append(line+"\r\n");}return builder.toString();}}
【服务端】
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得到输入流InputStream inputStream =socket.getInputStream();BufferedInputStream bufferedInputStream =new BufferedInputStream(inputStream);byte[] bytes =StreamUtils.streamToByteArray(bufferedInputStream);BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(new FileOutputStream("src\\jmq.jpg"));bufferedOutputStream.write(bytes);bufferedOutputStream.close();//向客户端回复收到图片//通过socket获取到输出流[字符]BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bufferedWriter.write("服务端收到图片");bufferedWriter.flush();//把内容刷新//设置结束标记socket.shutdownOutput();//关闭其他资源bufferedWriter.close();bufferedInputStream.close();socket.close();serverSocket.close();}
}
【客户端】
package com.hspedu.upload;import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;/*** @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:\\jmq.jpg";BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));//bytes就是filePath对应的字节数组byte[] bytes= StreamUtils.streamToByteArray(bufferedInputStream);//通过Socket获取到输出流,将bytes数据发送给服务端OutputStream outputStream =socket.getOutputStream();BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(outputStream);bufferedOutputStream.write(bytes);//将文件写入到数据通道//关闭流bufferedInputStream.close();socket.shutdownOutput();//设置一个结束的标志//接收服务端的信息InputStream inputStream=socket.getInputStream();String message=StreamUtils.streamToString(inputStream);System.out.println(message);socket.shutdownInput();//关闭相关流inputStream.close();bufferedOutputStream.close();socket.close();}
}
6.netstat 指令
7.TCP 网络通讯不为人知的秘密
四、UDP 网络通信编程[了解]
1 基本介绍
2 基本流程
3.应用案例
A端口
package com.hspedu.udp;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;/*** @author 林然* @version 1.0* UDP 接收端*/
public class UDPReceiverA {public static void main(String[] args) throws IOException {//1.创建一个DatagramSocket 对象,准备接受数据DatagramSocket datagramSocket = new DatagramSocket(9999);//2.构建一个DatagramPacket准备接受数据//udp一个数据包大小限制在64K,不适用传递大量数据byte [] buf =new byte[64*1024];DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);//3.调用接收方法//填充到packet对象//提示: 当有数据包发送到 本机的 9999 端口时,就会接收到数据// 如果没有数据包发送到 本机的 9999 端口, 就会阻塞等待System.out.println("接收端 A 等待接收数据..");datagramSocket.receive(datagramPacket);//4 拆包int length= datagramPacket.getLength();//实际接收到的数据字节长度byte [] data =datagramPacket.getData();String s = new String(data, 0, length);System.out.println(s);String message="好的,收到";DatagramPacket datagramPacket1 =new DatagramPacket(message.getBytes(),message.getBytes().length, InetAddress.getLocalHost(),9998);datagramSocket.send(datagramPacket1);//关闭datagramSocket.close();System.out.println("A端退出");}
}
B端口
package com.hspedu.udp;import java.io.IOException;
import java.net.*;/*** @author 林然* @version 1.0* 发送端 B ====> 也可以接收数据*/
public class UDPSenderB {public static void main(String[] args) throws IOException {//1.创建 DatagramSocket 对象,准备在 9998 端口 接收数据DatagramSocket datagramSocket =new DatagramSocket(9998);//2 将需要发送的数据封装到Datagrampacket对象byte[] bytes = "hello,明天吃火锅".getBytes();//说明: 封装的 DatagramPacket 对象 bytes 内容字节数组 , bytes.length , 主机(IP) , 端口DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 9999);datagramSocket.send(datagramPacket);//3.=== 接收从 A 端回复的信息
//(1) 构建一个 DatagramPacket 对象,准备接收数据// 在前面讲解 UDP 协议时,老师说过一个数据包最大 64kbyte [] buf=new byte[1024*64];DatagramPacket datagramPacket1=new DatagramPacket(buf,buf.length);// 如果没有数据包发送到 本机的 9998 端口, 就会阻塞等待.datagramSocket.receive(datagramPacket1);int length =datagramPacket1.getLength();byte [] data=datagramPacket1.getData();System.out.println(new String(data,0,length));//关闭资源datagramSocket.close();System.out.println("B端退出");}
}
五、本章作业
1.作业一
【服务端】
package com.hspedu.homework;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*** @author 林然* @version 1.0*/
public class homework01_service {public static void main(String[] args) throws IOException {ServerSocket serverSocket =new ServerSocket(9999);System.out.println("服务器端口等待连接");Socket socket =serverSocket.accept();//接受数据InputStream inputStream =socket.getInputStream();BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(inputStream));String str=bufferedReader.readLine();System.out.println(str);String message="";if(str.equals("name")){message="Linran";}else if(str.equals("hobby")){message="java编程";}else {message="你说啥呢";}OutputStream outputStream=socket.getOutputStream();BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(outputStream));bufferedWriter.write(message,0,message.length());bufferedWriter.flush();socket.shutdownOutput();//关闭流bufferedWriter.close();bufferedReader.close();socket.close();serverSocket.close();}
}
【客户端】
package com.hspedu.homework;import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;/*** @author 林然* @version 1.0*/
public class homework01_client {public static void main(String[] args) throws IOException {//建立连接Socket socket=new Socket(InetAddress.getLocalHost(),9999);Scanner scanner=new Scanner(System.in);//用户输入String message =scanner.next();//获取输出流OutputStream outputStream =socket.getOutputStream();BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(outputStream));bufferedWriter.write(message,0,message.length());bufferedWriter.flush();socket.shutdownOutput();//发送等待回复InputStream inputStream =socket.getInputStream();BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(inputStream));String data =bufferedReader.readLine();System.out.println(data);//关闭流bufferedReader.close();bufferedWriter.close();socket.close();}
}
2.作业二
【接收端】
package com.hspedu.homework;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;/*** @author 林然* @version 1.0*/
public class homework02_A_receive {public static void main(String[] args) throws IOException {DatagramSocket datagramSocket =new DatagramSocket(9999);byte [] buf =new byte[1024*64];DatagramPacket datagramPacket=new DatagramPacket(buf,buf.length);System.out.println("等待;连接");datagramSocket.receive(datagramPacket);int length =datagramPacket.getLength();byte [] data =datagramPacket.getData();String message =new String(data,0,length);//注意这里第三个参数不要用data.lengthSystem.out.println(message);String answer =" ";if("四大名著是哪些".equals(message)){answer="四大名著是<红楼梦>........";}else {answer="What?";}System.out.println(answer);DatagramPacket datagramPacket1 =new DatagramPacket(answer.getBytes(),answer.getBytes().length, InetAddress.getLocalHost(),9998);datagramSocket.send(datagramPacket1);//关闭流datagramSocket.close();}
}
【发送端】
package com.hspedu.homework;import java.io.IOException;
import java.net.*;
import java.util.Scanner;/*** @author 林然* @version 1.0*/
public class homework02_B_send {public static void main(String[] args) throws IOException {//建立我方监听端口DatagramSocket datagramSocket =new DatagramSocket(9998);//等待用户输入Scanner scanner =new Scanner(System.in);String message=scanner.next();//封装DatagramPacket datagramPacket =new DatagramPacket(message.getBytes(),message.getBytes().length, InetAddress.getLocalHost(),9999);//发送datagramSocket.send(datagramPacket);//获取回复信息byte [] buf =new byte[1024*64];DatagramPacket datagramPacket1 =new DatagramPacket(buf,buf.length);datagramSocket.receive(datagramPacket1);int length =datagramPacket1.getLength();byte [] data =datagramPacket1.getData();String answer =new String(data,0,length);System.out.println(answer);//关闭流datagramSocket.close();}
}
3.作业三
【服务器端】
package com.hspedu.homework;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;/*** @author 林然* @version 1.0*/
public class homework03_server {public static void main(String[] args) throws Exception {ServerSocket serverSocket=new ServerSocket(9999);System.out.println("等待连接");Socket socket =serverSocket.accept();//获取数据InputStream inputStream =socket.getInputStream();//利用工具类String filename=StreamUtils.streamToString(inputStream);System.out.println("客户希望下载的文件名"+filename);//判断是否存在String filename1="src\\"+filename;File file =new File(filename1);System.out.println("客户希望下载的文件名"+filename1);String send_filepath =filename1;if(!file.exists()){send_filepath="src\\无名.mp3";}BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(send_filepath));//利用工具类byte [] bytes=StreamUtils.streamToByteArray(bufferedInputStream);//输出BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(socket.getOutputStream());bufferedOutputStream.write(bytes);bufferedOutputStream.flush();socket.shutdownOutput();//关闭流bufferedOutputStream.close();bufferedInputStream.close();socket.close();serverSocket.close();}
}
【客户端】
package com.hspedu.homework;import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;/*** @author 林然* @version 1.0*/
public class homework03_client {public static void main(String[] args) throws Exception {Scanner scanner =new Scanner(System.in);//用户输入System.out.println("请输入你要查找的文件名");String filename=scanner.next();//建立连接Socket socket =new Socket(InetAddress.getLocalHost(),9999);OutputStream outputStream =socket.getOutputStream();BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(outputStream));//写入bufferedWriter.write(filename);bufferedWriter.flush();socket.shutdownOutput();//获取回复InputStream inputStream =socket.getInputStream();BufferedInputStream bufferedInputStream =new BufferedInputStream(inputStream);byte [] data =StreamUtils.streamToByteArray(bufferedInputStream);String dest_path ="e:\\"+filename;File file =new File(dest_path);BufferedOutputStream bufferedOutputStream =new BufferedOutputStream(new FileOutputStream(file));bufferedOutputStream.write(data);bufferedOutputStream.flush();//关闭流bufferedOutputStream.close();bufferedInputStream.close();bufferedWriter.close();socket.close();}
}
【工具类】
package com.hspedu.homework;import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;/*** 此类用于演示关于流的读写方法**/
public class StreamUtils {/*** 功能:将输入流转换成byte[], 即可以把文件的内容读入到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);//把读取到的数据,写入bos }byte[] array = bos.toByteArray();//然后将bos 转成字节数组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){builder.append(line+"\r\n");}return builder.toString();}}