你好,游客 登录
背景:
阅读新闻

8.4 Scala网络编程示例

[日期:2021-09-27] 来源:  作者: [字体: ]

本文来自艾叔编著的《零基础快速入门Scala》免费电子书,添加文末艾叔微信,获取完整版的PDF电子书

8.4  Scala网络编程示例

下面的示例实现了客户端(MsgSend)向服务端(MsgRcv)通过网络发送消息的功能,具体描述如下。

8.4.1  客户端MsgSend

MsgSend程序流程:1. 从控制台上读入用户输入(字符串);2. 判断是否是字符串quit,如果是,退出程序,如果不是,跳到33. MsgRcv创建TCP连接,MsgRcv端口是9999,连接成功后,向MsgRcv发送字符串;4. 读取MsgRcvACK反馈,并打印;5. 跳到1,循环。例子代码如下。

1行,引入StIn所在package,用于读个取控制台用户输入;

2行,设置程序退出标识notQuittrue表示不退出,false表示退出;

3行,开始while循环,判断notQuit

4行,读取1行数据,存储到str

5~7行,如果strquit,则退出循环;

8行,引入Socket所在packageScala网络编程使用的是java接口;

9行,创建Socket,并与服务端IP127.0.0.1(因为是在同一台机器,用的是127.0.0.1,不同的机器替换IP即可),端口9999建立连接;

10行,引入ObjectOutputStream所在package,用于向MsgRcv发送Object

11行,创建ObjectOutputStream对象;

12行,调用os.writeObject,向MsgRcv发送Object,将String对象发送过去;

14~16行,读取MsgRcv返回的Object

17~22行,判断返回的Object是否为String,如果是,打印,如果不是,给出提示;

23行,关闭此次连接,连接不用后,一定要记得关闭。

      1 import scala.io.StdIn

      2 var notQuit = true

      3 while(notQuit) {

      4   val str = StdIn.readLine()

     5   if(str.equals("quit")){

      6     notQuit = false

      7   }else{

      8     import java.net.Socket

      9     val sc = new Socket("127.0.0.1", 9999)

     10     import java.io.ObjectOutputStream

     11     val os = new ObjectOutputStream(sc.getOutputStream)

     12     os.writeObject(str)

     13

     14     import java.io.ObjectInputStream

     15     val is = new ObjectInputStream(sc.getInputStream)

     16     val msg = is.readObject()

     17     if(msg.isInstanceOf[String]){

     18       val rs = msg.asInstanceOf[String]

     19        println("rs " + rs)

     20     }else{

     21        println("rs is not String")

     22     }

     23     sc.close()

     24   }

     25 }

8.4.2  服务端MsgRcv

MsgRcv程序流程:1. 创建Socket,绑定IP、端口,开始监听;2. 接受外部连接请求,创建客户端连接;3. 创建ObjectInputStream,读取MsgSend发送过来的Object对象;4. 使用match进行类型匹配,可以匹配String等不同类型,���据不同的类型,给出提示;5. 使用ObjectOutputStreamMsgSend发送ACK反馈;6. 关闭客户端连接。

1行,引入Socket所在的packageScala使用java所提供网络编程接口,它属于Socket编程;

2行,创建Socket服务端,绑定端口9999,所谓端口,就是服务标识,例如22端口标识ssh服务,21端口标识ftp服务,80端口是http服务,用户自定义端口编号从1024开始,到65535结束,使用ip+端口,可以唯一标识一台主机上的服务;

4行,while循环;

5行,监听并接受外部请求,创建客户端连接cli

6~7行,创建ObjectInputStream对象,用于读取MsgSend发送过来的Object

8~9行,创建ObjectOutputStream对象,向MsgSend发送Object

11行,读取MsgSend发送过来的Object

12~15行,类型匹配,可以匹配MsgSend发送过来的各种数据类型,包括自定义类型;

17行,向MsgSend发送Object

18行,清空发送缓冲,立即发送;

20行,关闭客户端连接cli(一定要记得);

23行,整个程序退出时,关闭sev连接。

      1 import java.net.ServerSocket

      2 val sev = new ServerSocket(9999)

      3

      4 while (true) {

      5   val cli = sev.accept()

      6   import java.io.ObjectInputStream

      7   val is = new ObjectInputStream(cli.getInputStream)

      8   import java.io.ObjectOutputStream

      9   val os = new ObjectOutputStream(cli.getOutputStream)

     10

     11   val msg = is.readObject()

     12   val rs = msg match{

     13     case str: String => println("rcv string: " + str)

     14     case _ => println("rcv nothing")

     15   }

     16

     17   os.writeObject("OK")

     18   os.flush()

     19

     20   cli.close()

     21 }

     22

     23 sev.close()

总结

  • MsgSendMsgRcv之间使用的TCP协议,除此外,常用的网络协议还有UDPTCP是可靠的面向连接的,UDP是无连接,不可靠的,两者编程方法也不同,需要加以注意;
  • MsgRcv提供了一个消息处理框架,即使用match进行类型匹配,可以自定义各种消息类型(它们都是一个类),使用此框架进行解析;
  • 消息发送使用ObjectOuptputStream,消息接收使用ObjectInputStream
  • 连接、Socket不使用时要记得关闭,它们都是有资源限制的。

 

加艾叔微信,加入Linux(Shell+Zabbix)、大数据(Spark+Hadoop)、云原生(Docker+Kubernetes)技术交流群

 

关注艾叔公众号,获取更多一手信息

 

收藏 推荐 打印 | 阅读:
相关新闻