Java 之网络编程
2017-09-14 20:20
190 查看
网络模型
- OSI 模型, 把网络通信的工作分为七层.
- TCP/IP 模型, 把网络通信的工作分为四层
-
应用层
- 传输层
- 网际层
- 主机至网络层
网络通信要素 (java.net 包)
- IP 地址 (InetAddress) - 端口号 - 用于标识进程的逻辑地址, 不同进程的标识 - 有效端口: 0~65535, 其中 0~1024 为系统使用或保留端口 - 2 的16次方 = 65536 - 传输协议 - 通讯的规则 - 常见协议: TCP, UDP
IP
- java.net 包中, InetAddress 类 - 网络模型中的网际层 - 没有构造函数, 有非静态方法(单例设计模式)
域名解析
Socket
- Socket 就是为网络服务提供的一种机制 - 通信的两端都有 Socket - 网络通信其实就是 Socket 间的通信
UDP
- 特点:
-
将数据及源和目的封装到数据包中, 不需要建立连接
- 每个数据包的大小限制在 64K 内
- 因无连接, 是不可靠的协议
- 不需要建立连接,速度快
- 类似于生活中的对讲机
- 在 java 中的体现
-
DatagramSocket 用来发送和接收数据报包的 socket
- DatagramPacket 表示数据报包
// 需求一: 创建 UDP 传输的发送端 /* * 思路: * 1. 建立 UDP 的 socket 服务 * 2. 将要发送的数据封装到数据包中 * 3. 通过 UDP 的 socket 服务将数据包发送出去 * 4. 关闭 socket 服务 */ public static void main(String[] args) throws IOException { // 1. 创建 udp 的 socket 服务, 使用 DatagramSocket 对象 DatagramSocket ds = new DatagramSocket(); // 2. 将要发送的数据封装到数据包中 String str = "udp传输演示:哥们来了!"; // 使用 DatagramPacket 将数据封装到该对象包中 byte[] buf = str.getBytes(); DatagramPacket dp =new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.100"), 9999); // 指定的为接收端的端口号 // 3. 通过 udp 的 socket 服务将数据包发送出去, 使用 send 方法 ds.send(dp); // 4. 关闭 socket 服务 ds.close(); } // 需求二: 创建 UDP 传输的接收端 /* * 思路: * 1. 建立 udp 的 socket 服务, 因为是要接收数据, 必须要明确一个端口号 * 2. 创建数据包, 用于存储接收到的数据, 方便用数据包对象的方法解析这些数据 * 3. 使用 socket 服务的 receive 方法将接收的数据存储到数据包中 * 4. 通过数据包的方法解析数据包中的数据 * 5. 关闭资源 * / public static void main(String[] args) throws IOException{ // 1. 创建 socket 接收服务, 明确接收端口 DatagramSocket ds = new DatagramSocket(9999); // 2. 创建数据包, 用于存储接收到的数据 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); // 3. 接收数据 ds.receive(dp); // 4. 使用数据包对象的方法, 解析其中的数据, 比如地址, 端口, 数据内容 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+"..."+port+"..."+text); }
TCP
- 建立连接,形成传输数据的通道 - 在连接中进行大数据量传输 - 通过三次握手完成连接,是可靠协议 - 必须建立连接,效率会稍低 - 类似生活中的手机
// 需求一: 客户端发送数据到服务端 /* * 思路: * 1. 创建 tcp 客户端 socket 服务. 使用的是 Socket 对象 * 建议该对象一创建就明确目的地, 即指定要连接的主机 * 2. 如果连接建立成功, 说明数据传输通道已建立 * 该通道就是 socket 流, 是底层建立好的. * 既然是流,说明这里既有输入,又有输出. * 想要输入或者输出流对象, 可以找 socket 对象获取,而不能使用 new 创建 * 可以通过 getOutputStream() 和 getInputStream() 来获取两个字节流 * 3. 使用输出流, 将数据写出 * 4. 关闭资源 * / public static void main(String[] args){ // 1. 创建客户端 socket 服务 Socket socket = new Socket("192.168.1.100",10001); // 2. 获取 socket 流中的输出流对象 OutputStream out = socket.getOutputStream(); // 3. 使用输出流将指定的数据写出去 out.write("tcp演示: 哥们又来了!".getBytes()); // 4. 关闭资源 socket.close(); } // 需求二: 服务端接收客户端发送过来的数据, 并打印在控制台上 /* * 思路: * 1. 创建服务端 socket 服务, 通过 ServerSocket 对象 * 2. 服务端必须对外提供一个端口,否则客户端无法连接 (监听端口) * 3. 获取连接过来的客户端对象 * 4. 通过客户端对象获取 socket 流读取客户端发来的数据, 并打印在控制台上 * 5. 关闭资源. 包括客户端资源和服务端资源 */ public static void main(String[] args){ // 1. 创建服务端对象 ServerSocket ss = new ServerSocket(10001); // 2. 获取连接过来的客户端对象 Socket s = ss.accept(); String ip = s.getInetAddress().getHostAddress(); // 通过 socket 对象获取输入流,并读取数据 InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); String text = new String(buf,0,len); System.out.println(ip+"..."+text); // 关闭资源 s.close(); ss.close(); }
// 需求三: 上传文本文档 // TCP 客户端 public static void main(String[] args) throws IOException{ // 1. 创建客户端对象 Socket s = new Socket("192.168.1.100", 10005); // 2. 文本文件与输入流关联 BufferedReader bufr = new BufferedReader(new FileReader("c:\\client.txt")); // 3. 获取 socket 的输出流并装饰 PrintWriter out = new PrintWriter(s.getOutputStream(),true); // 4. 将文件写入到输出流 String line = null; while((line=bufr.readLine())!=null){ out.println(line); } // 告诉服务端, 客户端写完了. 结束标记 s.shutdownOutput(); // 5. 读取服务端发来的数据 BufferedReader bufrIn = new BufferedReader(new InputStreamReader(s.getInputStream())); String str = bufrIn.readLine(); System.out.println(str); // 6. 关闭资源 bufr.close(); s.close(); } // TCP 服务端 public static void main(String[] args) throws IOException{ // 1. 创建服务端对象 ServerSocket ss = new ServerSocket(10005); // 2. 获取客户端对象 Socket s = ss.accept(); // 3. 通过 socket 对象获取输入流 BufferedReader bufrIn = new BufferedReader(new InputStreamReader(s.getInputStream())); // 4. 服务端文件与输出流关联 BufferedWriter bufw = new BufferedWriter(new FileWriter("c:\\server.txt")); // 5. 从输入流中读取数据, 并写入到文件中 String line = null; while((line=bufIn.readLine())!=null){ bufw.write(line); bufw.newLine(); bufw.flush(); // 写入一次后,需要刷新才能写入到文件中 } // 6. 反馈给客户端信息 PrintWriter out = new Printer(s.getOutputStream(),true); out.println("上传成功"); // 7. 关闭资源 bufw.close(); s.close(); ss.close(); }
参考资料
相关文章推荐
- java网络编程之Netty第一个程序(四)
- java笔记(七):网络编程
- Java基础知识强化之网络编程笔记11:TCP之TCP协议上传文本文件
- day12 Java IO 中的文件路径 Propertity 文件 Socket 网络编程
- java中的网络编程
- java 网络编程【7】 如何检测和解决端口冲突问题?
- Java 高层网络编程
- Java网络编程(tcp在服务器上应用多线程)
- java网络编程
- 读书笔记-java网络编程-5URL和URI-简述
- 浅谈JAVA中如何利用socket进行网络编程(一)
- java网络编程小结1
- java网络编程之application/x-www-form-urlencoded MIME
- JAVA的网络编程基础概念
- Java网络编程从入门到精通(7):用getHostAddress方法获得IP地址
- Java学习笔记―第十二章 Java网络编程入门
- 黑马程序员——Java基础---网络编程
- 黑马程序员-java 网络编程
- 黑马程序员----Java网络编程