目录
一. 网络基础
BS(Browser/Server,浏览器/服务器架构)
CS(Client/Server,客户端/服务器架构)
二. TCP Socket通信
三. Socket类
四. 聊天实例
五. UDP Socket
六. 数据交换格式
一. 网络基础
网络是将不同地理位置的计算机和设备连接在一起,使它们能够相互通信和共享资源的系统。
网络的组成部分:
- 节点:包括计算机、服务器、智能手机、路由器等设备。
- 通信链路:用于连接节点的物理介质,如双绞线、光纤、无线电波等。
网络的类型:
- 局域网(LAN):覆盖较小的地理范围,如办公室、学校或家庭。
- 广域网(WAN):跨越较大的地理区域,通常由多个局域网通过公共网络连接而成。
网络协议:
协议是网络中设备之间通信的规则和标准。常见的网络协议包括:
- TCP/IP(传输控制协议/网际协议):是互联网的基础协议簇,包括 IP、TCP、UDP 等。
- IP 负责在网络中寻址和路由数据包。
- TCP 提供可靠的、面向连接的数据传输服务。
- UDP 提供不可靠的、无连接的数据传输服务。
- HTTP(超文本传输协议):用于在 Web 浏览器和服务器之间传输网页和相关数据。
- FTP(文件传输协议):用于在网络上传输文件。
IP 地址和域名:
- IP 地址:是给网络上的设备分配的唯一标识符,如 192.168.1.1 。
- 域名:如 www.example.com ,更便于人类记忆,通过域名系统(DNS)解析为对应的 IP 地址。
网络拓扑结构:
描述网络中设备的连接方式,常见的有总线型、星型、环型、树型和网状型。
例如,在一个公司的网络中,各个部门的计算机通过交换机组成局域网,这些局域网再通过路由器连接到互联网,员工可以通过网络访问公司内部的服务器获取资源,也可以通过浏览器访问外部网站,这都依赖于网络的各种组成部分、协议和拓扑结构的协同工作。
BS(Browser/Server,浏览器/服务器架构)
在 BS 架构中,客户端使用浏览器作为用户界面,服务器端负责处理业务逻辑和数据存储。用户通过浏览器向服务器发送请求,服务器处理请求后将结果返回给浏览器展示。
优点:
- 部署和维护方便,只需更新服务器端。
- 跨平台性好,用户通过各种支持浏览器的设备访问。
- 成本相对较低,无需为每个客户端安装软件。
例如,常见的在线办公软件、电商平台大多采用 BS 架构。
CS(Client/Server,客户端/服务器架构)
CS 架构中,客户端和服务器端都承担一定的功能。客户端通常具有更丰富的用户界面和部分处理能力,服务器端主要负责数据管理和核心业务逻辑。
优点:
- 响应速度快,部分处理在客户端完成。
- 可离线使用,一些功能在客户端本地实现,不依赖网络。
例如,大型游戏、专业设计软件等常采用 CS 架构。
二. TCP Socket通信
TCP Socket 通信是一种基于 TCP 协议的网络编程接口,用于在不同的进程或计算机之间进行可靠的数据传输。
TCP 协议的特点:
- 面向连接:在通信之前,客户端和服务器端需要建立连接。
- 可靠传输:通过确认、重传和拥塞控制等机制保证数据的无差错、按顺序到达。
- 字节流服务:TCP 把应用程序交下来的数据看成一连串的无结构的字节流。
Socket 概念:
Socket 是应用程序与网络协议栈之间的接口,它封装了通信的细节,使得开发者可以专注于应用逻辑。
TCP Socket 通信的工作流程:
服务器端:
- 创建
ServerSocket
对象,并指定监听的端口。- 调用
accept()
方法阻塞等待客户端的连接请求。当有客户端连接时,返回一个新的Socket
对象用于与该客户端通信。- 通过这个新的
Socket
对象的输入输出流进行数据的接收和发送。
客户端:
- 创建
Socket
对象,指定服务器的 IP 地址和端口。- 连接服务器,如果连接成功,就可以通过该
Socket
对象的输入输出流与服务器进行数据交互。
数据传输:
可以使用 InputStream
读取数据,使用 OutputStream
写入数据。数据可以是字节形式,也可以通过转换为字符或其他数据类型进行处理。
异常处理:
在通信过程中,可能会出现各种异常,如连接失败、读写异常等,需要进行适当的捕获和处理。
关闭连接:
通信完成后,需要关闭 Socket
、输入输出流等资源,以释放系统资源。
应用场景:
- 即时通讯应用:如聊天软件。
- 文件传输:保证文件数据的完整和正确传输。
- 分布式系统中的节点通信:实现不同节点之间的协调和数据交换。
例如,一个在线文件下载服务,服务器端等待客户端的连接请求,客户端连接后发送文件请求,服务器端读取文件并通过 TCP 连接将数据发送给客户端。
总之,TCP Socket 通信是一种强大而灵活的网络通信方式,为各种网络应用提供了可靠的数据传输基础。但在实际开发中,需要仔细处理各种情况,以确保通信的稳定性和正确性。
三. Socket类
在 Java 中,Socket
类用于实现客户端与服务器之间的网络通信。
构造方法:
Socket(String host, int port)
:创建一个连接到指定主机和端口的套接字。Socket(InetAddress address, int port)
:使用指定的 IP 地址和端口创建套接字。
常用方法:
getInputStream()
:返回此套接字的输入流,用于读取服务器发送的数据。getOutputStream()
:返回此套接字的输出流,用于向服务器发送数据。getInetAddress()
:获取连接的远程主机的 IP 地址。getPort()
:获取连接的远程端口。close()
:关闭套接字,释放相关资源。
示例代码(客户端):
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SocketClientExample {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 8080)) { // 连接本地主机的 8080 端口
OutputStream outputStream = socket.getOutputStream();
String message = "Hello, Server!";
outputStream.write(message.getBytes());
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
String response = new String(buffer, 0, bytesRead);
System.out.println("Server response: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述示例中,创建了一个到指定地址和端口的 Socket
对象,然后向服务器发送数据,并接收服务器的响应。
注意事项:
- 在使用完
Socket
后,一定要调用close()
方法关闭,以释放资源。 - 网络通信可能会出现各种异常,如连接超时、IO 异常等,需要进行适当的异常处理。
Socket
类为 Java 中的网络编程提供了基础,使得开发基于 TCP 协议的客户端应用变得相对简单和直观。
四. 聊天实例
服务端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ChatServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("服务器启动,等待客户端连接...");
Socket socket = serverSocket.accept();
System.out.println("客户端已连接");
// 输入输出流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String message;
while ((message = in.readLine())!= null) {
System.out.println("客户端: " + message);
out.println("服务器: 已收到你的消息 - " + message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 8888)) {
// 输入输出流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String message;
while ((message = consoleReader.readLine())!= null) {
out.println(message);
System.out.println("服务器: " + in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上述代码中,服务端监听 8888 端口,等待客户端连接。客户端连接到本地的 8888 端口,并与服务端进行交互。用户在客户端输入消息,服务端接收并回复,实现简单的聊天功能。
五. UDP Socket
在 Java 中,DatagramSocket
类用于实现用户数据报协议(UDP)的网络通信。
构造方法:
DatagramSocket()
:创建一个绑定到本地主机随机可用端口的DatagramSocket
对象。DatagramSocket(int port)
:创建一个绑定到指定本地端口的DatagramSocket
对象。DatagramSocket(int port, InetAddress laddr)
:创建一个绑定到指定本地地址和端口的DatagramSocket
对象。
常用方法:
send(DatagramPacket p)
:发送数据报。receive(DatagramPacket p)
:接收数据报。close()
:关闭套接字。
DatagramPacket
类:
用于封装要发送或接收的数据报。
构造方法:
DatagramPacket(byte[] buf, int length)
:用于接收数据报。DatagramPacket(byte[] buf, int length, InetAddress address, int port)
:用于发送数据报。
示例代码(发送端):
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSender {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket()) {
String message = "Hello, UDP!";
byte[] data = message.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(data, data.length, address, 8888);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
示例代码(接收端):
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceiver {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket(8888)) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String receivedMessage = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received: " + receivedMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP 的特点:
- 无连接:不需要在发送数据之前建立连接。
- 不可靠:不保证数据报的顺序、不重复和不丢失。
- 高效:开销小,适用于实时性要求较高、对数据准确性要求相对较低的场景。
总之,UDP Socket
提供了一种快速但相对简单和不可靠的数据传输方式,在某些特定的应用中具有优势。
六. 数据交换格式
数据交换格式是用于在不同系统、应用程序或网络之间传输和共享数据的特定结构和规则。
常见的数据交换格式包括:
-
JSON(JavaScript Object Notation):
- 特点:轻量级、易于阅读和编写、易于机器解析和生成。
- 示例:
{"name": "John", "age": 30, "city": "New York"}
- 广泛应用于 Web 应用的前后端数据交互、配置文件等。
-
XML(eXtensible Markup Language):
- 特点:具有良好的自描述性、格式规范、可扩展性强。
- 示例:
<person><name>John</name><age>30</age><city>New York</city></person>
- 常用于数据存储、配置文件、Web 服务等。
-
CSV(Comma-Separated Values):
- 特点:简单、以逗号分隔值,适合表格数据。
- 示例:
name,age,city\nJohn,30,New York
- 常用于数据导出、导入,电子表格处理。
-
YAML(YAML Ain't Markup Language):
- 特点:简洁、易读,对缩进敏感。
- 示例:
name: John
age: 30
city: New York
- 常用于配置文件。
- Protobuf(Protocol Buffers):
- 特点:高效的二进制格式、跨语言支持好、数据压缩率高。
- 需要先定义
.proto
文件来描述数据结构。
例如,在一个电商网站中,商品信息可能以 JSON 格式从后端服务器发送到前端页面进行展示;而在数据备份时,可能会将用户数据以 CSV 格式导出。
选择数据交换格式时,需要考虑数据的复杂性、可读性、传输效率、跨语言支持等因素。