scala akka 修炼之路3(基于java nio的socket编程)

package cn.yangg.scala.base.init

 

import java.io.Closeable

import java.nio.channels.ServerSocketChannel

import java.net.InetSocketAddress

import java.nio.channels.SocketChannel

import java.nio.charset.Charset

import java.nio.ByteBuffer

import akka.actor.Actor

import java.nio.channels.Selector

import java.nio.channels.SelectionKey

import akka.actor.ActorSystem

import akka.actor.Props

 

case class StartService(port: Int)

class ServerActor extends Actor {

  val serverChannel = ServerSocketChannel.open()

  valserverSocket =serverChannel.socket()

  val selector = Selector.open()

 

  val buffer = ByteBuffer.allocate(1024)

  val charset = Charset.forName("UTF-8")

  val charDecoder =charset.newDecoder()

 

  def receive = {

    case StartService(port) =>

      this.serverListenerStart(port)

  }

  def serverListenerStart(port: Int) = {

    serverSocket.bind(new InetSocketAddress(port))

    serverChannel.configureBlocking(false)

    serverChannel.register(selector, SelectionKey.OP_ACCEPT)

    var n =0

    while (true) {

      n = selector.select()

      if (n >0) {

        val it =selector.selectedKeys().iterator()

        while (it.hasNext()) {

          val key =it.next()

          it.remove() 删除已选key,防止重复处理

          if (key.isAcceptable()) {

            val server =key.channel().asInstanceOf[ServerSocketChannel]

            val channel =server.accept()

            println(channel)

            if (null !=channel) {

              channel.configureBlocking(false)

              channel.register(selector, SelectionKey.OP_READ)

            }

          } else if (key.isReadable()) {

            val socket =key.channel().asInstanceOf[SocketChannel]

            var size: Int =0

            println("read data ....." + key)

            buffer.clear()

            size = socket.read(buffer)

            while (size >0) {

              buffer.flip()

              charDecoder.decode(buffer.asReadOnlyBuffer())

              .toString().split("\\.\\.\\.\\.").foreach(println)

              buffer.clear()

              size = socket.read(buffer)

            }

            if (size == -1) { //当对端主动关闭后移除key,要不然selector会一直返回可读

              socket.close()

              selector.selectedKeys().remove(key)

            }

          }

        }

      }

    }

  }

}

class ClientActor extends Actor {

  val client = SocketChannel.open()

  val buffer = ByteBuffer.allocate(1024)

  def receive = {

    case StartService(port) =>

      clientStart(port)

  }

  def clientStart(port: Int) {

    client.connect(new InetSocketAddress(port))

    while (true) {

 

      for (i <-1 to5) {

        buffer.clear()

        buffer.put(("hello server" +i +"....").getBytes("utf8"))

        buffer.flip()

        client.write(buffer)

      }

 

      Thread.sleep(1000)

      println(System.currentTimeMillis() + "message to parent....")

    }

  }

}

object SocketStart {

  def main(args: Array[String]) {

    this.akkaSocketTest("socketActor",11111)

  }

  def akkaSocketTest(actorName: String, port: Int) = {

    val actorSystem = ActorSystem(actorName)

    val serverActor =actorSystem.actorOf(Props[ServerActor],"serverActor")

    val clientActor =actorSystem.actorOf(Props[ClientActor],"clientActor")

    val startCMD =new StartService(port)

 

    serverActor !startCMD

    clientActor !startCMD

  }

}

http://blog.csdn.net/yangguo_2011/article/details/28446807

 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值