为了方便阅读,在此声明两种高亮含义
1 重点内容 2 笔者的总结
初入网络编程
网络编程的主要内容之一就是数据的交互处理。网络编程模型中一般有客户端与服务端两个核心组成部分,客户端可以向服务端进行请求数据的发送,服务端在接受到客户端的请求后,利用其自身定义的业务逻辑对数据进行处理,并将处理后的数据相应给客户端。
客户端与服务端之间的通信依靠Socket(套接字)完成,在通信过程中数据以字节流的形式传输,客户端的数据输出对服务端而言就是输入,反过来服务端的响应输出对客户端就是输入。
为了实现数据的有效传输,还有一个标准的OSI(Open System Interconnection,开放系统互连)七层模型。这七层模型分别为物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
OSI七层模型对要发送的数据进行处理,而在接受后对接收到的内容进行反向处理,获取原始数据具体处理流程如上图所示 。OSI了解即可,程序员需要关注的是如何实现,实现了再谈原理。
Java的网络编程
作为程序员,我们其实只需要对网络模型有一个大致的了解,初学网络编程的时候我们是不需要明确了解每网络交互的细节是怎么实现的。我们需要关心的只有如何使用Java或者任意一种编程语言实现不同端口的交互。
在Java中为了便于网络程序的开发,java.net包提供了ServerSocket与Socket两个处理类。其中ServerSocket主要工作在服务端,需要与一个具体的端口进行绑定,随后再次端口上等待客户端的连接请求。对于服务端来讲,每一个连接请求都使用一个Socket对象实例进行描述,在获得客户端的Socket对象实例之后就可以通过InputStream与OutputStream实现数据的接收与发送。
通俗来讲就是:运行服务端等待请求->运行客户端发出请求->服务端得到客户端发出的请求并响应->客户端根据服务端的响应执行相关操作
简单实例1
希望可以通过一段最简单的程序来讲解如何实现网络编程,如下。Server端和Client端分别是两个不同且独立的程序,但通过ServerSocket和Socket指定相同的‘8888’号端口,从而实现了两个独立程序的网络通信。
服务端
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8888); // 设置服务监听端口
System.out.println("【Server】客户端开始监听"); // 打印提示信息
Socket client = server.accept(); // 等待客户端连接
PrintStream out = new PrintStream(client.getOutputStream()); // 获取客户端输出流
out.println("这条是来自Server端的信息");
client.shutdownOutput();
client.close();
}
}
客户端
public class Client {
public static void main(String[] args) throws IOException {
Socket client = new Socket("localhost",8888);
Scanner scanner = new Scanner(client.getInputStream());
if(scanner.hasNext()){
System.out.println("【Client】"+scanner.next());
}
client.shutdownInput();
client.close();
}
}
操作及结果
(1)运行Server端,终端输出“【Server】客户端开始监听”
(2)运行Client端,终端输出“【Client】这条是来自Server端的信息”,Client结束
(3)返回Server端查看,终端显示Server结束。
具体的运行流程
当我们启动了Server端,Server就开始监听8888号端口有无客户端的输入流。当我们启动了Client端,向8888号端口传入了数据,Server就停止阻塞,进而向Client端口传入"这条是来自Server端的信息"这一条信息,Client接收到信息,并打印出来。
细节问题
server.accept()方法会使服务端阻塞,直到从Client端得到了信息,服务端才继续运行。
两个程序连接的建立是依靠Socket和ServerSokcet,并指定对应端口8888而实现的
至此简单实例的讲解就完成了
如果有哪里遗漏、错误或者不清楚的地方欢迎各位大佬指正!