网络分层
为了减少网络设计的复杂性

网络编程
通过套接字,达到进程间互相通信的目的。 Socket
科学家们把网络编程的基本模型使用 Java 语言实现好交给程序员,我们只需要在科学家提供的模型 Socket 中进行编写少量的代码就能编写网络程序。
网络编程要解决的问题:
- 如何无误的吧数据发送给指定的机器
- 如何传输数据
- 如何将数据发送给指定的应用
网络传输三要素:
InetAddress ip 地址类
传输层协议 TCP
在网络编程中,需要设计出一个高效、可靠的多线程网络程序需要涉及的知识点太广泛了,不是随便什么人都能完成。
所有科学家经过长时间的设计改良后把网络编程封装好,提供出面向传输层协议的API
我们只需要针对不同的传输层协议进行网络编程即可,
- 面向无连接的 UDP 协议,传输效率高,数据完整性不可靠
- 面向有链接的 TCP 协议,需要经过3次握手,建立连接后才能通讯,传输效率低,数据完整性可靠。
- 传输可靠,传输大量数据(流模式),速度慢,建立连接需要开销。
在互联网程序中,这两种协议都很常见。
TCP 编程-客户端
三次握手(建立连接),四次挥手(断开连接)
往服务器发送数据,接受服务端返回的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public void testCilent() throws Exception {
Socket socket = new Socket("127.0.0.1", 8888); OutputStream out = socket.getOutputStream(); out.write("你好服务器...".getBytes("UTF-8")); socket.shutdownOutput(); InputStream in = socket.getInputStream(); byte[] buffer = new byte[1024]; int len = -1; len = in.read(buffer); while (len > 0) { System.out.println(new String(buffer, 0, len, "UTF-8")); } socket.shutdownInput(); socket.close(); }
|
TCP - 服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(); Socket socket = ss.accept(); InputStream in = socket.getInputStream(); byte[] buffer = new byte[1024]; int len = -1; while (len > 0) { System.out.println(new String(buffer, 0, len, "UTF-8")); len = in.read(buffer); } socket.shutdownInput(); OutputStream out = socket.getOutputStream(); out.write("你也好!我是服务端...".getBytes("UTF-8")); socket.shutdownOutput(); socket.close(); }
|
TCP 三次握手
TCP 建立连接需要经过3次握手:

- 客户端找到服务端后发生链接意向
- 服务端收到客户端连接意向后,询问确认
- 客户端回复确认。
模拟 Tomcat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package cn.lizhaoloveit.socket;
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket;
import lombok.AllArgsConstructor; import lombok.NoArgsConstructor;
@NoArgsConstructor @AllArgsConstructor public class RequestHandler implements Runnable { private Socket socket; @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String info = br.readLine(); while (info != null) { if ("".equals(info)) { break; } System.out.println(info); info = br.readLine(); } socket.shutdownInput(); PrintWriter out = new PrintWriter(socket.getOutputStream()); out.println("HTTP/1.1 200 OK"); out.println("Content-Type:text/html;charset=utf-8"); out.println(); out.println("<html><head></head><body>welcome to tomcat</body></html>"); out.flush(); socket.shutdownOutput(); socket.close(); } catch (Exception e) { } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package cn.lizhaoloveit.socket;
import java.net.ServerSocket; import java.net.Socket;
public class TomcatMock { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(8080); System.out.println("服务器启动成功"); while (true) {
Socket socket = ss.accept();
new Thread(new RequestHandler(socket)).start(); } } }
|