Socket的入门案例(上)
2018-01-03 15:29
309 查看
上一篇说到了如何开发高并发的应用,但篇幅所限有很多细节没有展开,此篇就远程消息调用的底层原理做以阐述。
远程消息调用的底层使用的是Socket通信技术。对于计算机通信来说,一共划分了7层体系标准。在这个体系标准中,每个分层都接收有它下一层所提供的特定服务。上下层之间进行交互时所遵循的约定叫做“接口”,同一层之间的交互遵循的约定的协议叫做“协议”。这七层分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。而Socket通信技术是属于这七层标准中的应用层的技术,我们在使用Socket进行通信的时候,实际上是在调用java封装好的接口完成底层数据的通信,Socket通信的接口封装并屏蔽很多通信的细节,对于程序员来说也无需关心底层的细节。在Socket技术中,有两个角色,分别是服务器和客户,理解了这两个通信的角色的任务和通信步骤,就明白了Socket技术。原理如下表(注意序号的顺序)。
代码如下:
服务器端代码:ServerService.class
线程任务:ServerTask.class
客户端:ClientService.class
此篇对Socket通信的基础做了介绍,但是仅仅是对Socket使用的一个入门,下一篇将在此基础上,进一步演化:服务器端接收到客户端发送过来的数据后,如何处理,涉及到服务器端(远程)方法(消息)的调用的原理。
远程消息调用的底层使用的是Socket通信技术。对于计算机通信来说,一共划分了7层体系标准。在这个体系标准中,每个分层都接收有它下一层所提供的特定服务。上下层之间进行交互时所遵循的约定叫做“接口”,同一层之间的交互遵循的约定的协议叫做“协议”。这七层分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。而Socket通信技术是属于这七层标准中的应用层的技术,我们在使用Socket进行通信的时候,实际上是在调用java封装好的接口完成底层数据的通信,Socket通信的接口封装并屏蔽很多通信的细节,对于程序员来说也无需关心底层的细节。在Socket技术中,有两个角色,分别是服务器和客户,理解了这两个通信的角色的任务和通信步骤,就明白了Socket技术。原理如下表(注意序号的顺序)。
客户端 | 服务端 |
1.创建一个ServerSocket,绑定到服务器的一个端口进行通信,并开启了服务器 | |
2.循环调用Socket.accept(),等待客户端接入 | |
3.创建Socket对象,向服务器发出请求建立连接 | |
4.链接建立后,从Socket中获取输入输出流, Socket.getInputStream() Socket.getOutputStream() 向Socket的输出流中放进数据 | |
5.当有客户端接入,启动一个新的线程,运行通信任务 | |
6.从Socket中获取输入输出流,从Socket的输入流中获取客户端传递过来的数据,并进行处理,然后放到Socket的输出流中 | |
7.接收到服务器端的数据后,返回,通信结束 |
服务器端代码:ServerService.class
public class ServerService { public static void main(String[] args) throws IOException { // 创建一个ServerSocket,绑定到服务器的3366端口上 ServerSocket server = new ServerSocket(); server.bind(new InetSocketAddress("localhost", 3366)); System.out.println("服务器开启了"); //服务器一直等着接受客户端的接入请求 while (true) { //Socket.accept()方法是一个阻塞方法,会一直等待客户端 Socket socket = server.accept(); //当有客户端请求,启动服务器上的线程去执行任务,此时服务器继续等待客户端接入 System.out.println("启动了一个线程负责通信"); new Thread(new ServerTask(socket)).start(); } } }
线程任务:ServerTask.class
public class ServerTask implements Runnable{ Socket socket ; InputStream in=null; OutputStream out = null; public ServerTask(Socket socket) { this.socket = socket; } @Override public void run() { try { //从socket连接中获取到与client之间的网络通信输入输出流 in = socket.getInputStream(); out = socket.getOutputStream(); //1.从网络通信输入流中读取客户端发送过来的数据 //将Socket输入流中的数据(客户端发送过来的数据在in中)用BufferedReader重新包装一下 //这样可以利用BufferedReader的方法按行读取 BufferedReader br = new BufferedReader(new InputStreamReader(in)); //注意:socketinputstream的读数据的方法都是阻塞的 //阻塞的意思:没有接受到数据的时候,服务端这个线程任务什么也不做,一直等待 String param = br.readLine(); System.out.println("服务端收到客户端信息:"+param); //2.将调用结果写到sokect的输出流中,以发送给客户端 //将Socket输出流用PrintWriter重新包装一下 PrintWriter pw = new PrintWriter(out); pw.println(param+" java"); pw.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { in.close(); out.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
客户端:ClientService.class
public class ClientService { public static void main(String[] args){ Socket socket = null; InputStream inputStream = null; OutputStream outputStream = null; try { //创建Socket对象,向服务器发出请求建立连接 socket = new Socket("localhost", 3366); // 从socket中获取输入输出流 inputStream = socket.getInputStream(); outputStream = socket.getOutputStream(); //通过Socket输出流,向服务器发送信息 PrintWriter pw = new PrintWriter(outputStream); pw.println("hello"); pw.flush(); System.out.println("客户端发送了字符:hello"); //在没收到服务器端的返回信息前,客户端一直阻塞 BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); String result = br.readLine(); System.out.println("客户端收到服务端的信息:"+result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { //完成通信 inputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
此篇对Socket通信的基础做了介绍,但是仅仅是对Socket使用的一个入门,下一篇将在此基础上,进一步演化:服务器端接收到客户端发送过来的数据后,如何处理,涉及到服务器端(远程)方法(消息)的调用的原理。
相关文章推荐
- Socket的入门案例(中)
- Python案例-网络编程-socket入门-server&client
- 在LiveCode中利用socket进行通信(1)--入门介绍
- MapReducer入门案例MyWordCount
- Lucene创建索引入门案例
- 26_mvc入门案例
- Spring MVC入门(3)---简单案例(2)
- CUDA3.2+VS2008+CUDA_VS_WIZARD配置详细说明及第一个入门案例
- Logstash 入门教程 -配置案例
- Spark RDD/Core 编程 API入门系列 之rdd案例(map、filter、flatMap、groupByKey、reduceByKey、join、cogroupy等)(四)
- Linux网络协议栈(一)——Socket入门(1)
- Spring学习-02:入门案例
- Python Socket通讯编程入门
- 基于C#的Socket开发快速入门(转载)
- 阿里开源数据库连接池druid 入门案例
- TensorFlow入门案例分析
- Python3 初学实践案例(7)tkinter 入门 GUI 的密码生成程序
- 嵌入式OS入门笔记-以RTX为案例:六.RTX的任务调度
- Python爬虫入门案例
- Socket入门