NioClient.java 3.82 KB
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
package com.lyms.hospitalapi;

import com.lyms.platform.common.utils.PropertiesUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
* Created by riecard on 2016/11/24.
*/
@Service
public class NioClient {

public static final String NIO_CLIENT_START = PropertiesUtils.getPropertyValue("nio_client_start");

private Selector selector = null;
static final int port = 8000;
private Charset charset = Charset.forName("UTF-8");
private SocketChannel sc = null;
private String name = "";
private static String USER_EXIST = "system message: user exist, please change a name";
private static String USER_CONTENT_SPILIT = "#@#";

@PostConstruct
public void init() throws IOException {
if ("1".equals(NIO_CLIENT_START)) {
}
selector = Selector.open();
//连接远程主机的IP和端口
sc = SocketChannel.open(new InetSocketAddress("192.168.5.250",port));
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
//开辟一个新线程来读取从服务器端的数据
new Thread(new ClientThread()).start();
//在主线程中 从键盘读取数据输入到服务器端
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine())
{
String line = scan.nextLine();
if("".equals(line)) continue; //不允许发空消息
if("".equals(name)) {
name = line;
line = name+USER_CONTENT_SPILIT;
} else {
line = name+USER_CONTENT_SPILIT+line;
}
sc.write(charset.encode(line));//sc既能写也能读,这边是写
}
}

private class ClientThread implements Runnable
{
public void run()
{
try
{
while(true) {
int readyChannels = selector.select();
if(readyChannels == 0) continue;
Set selectedKeys = selector.selectedKeys(); //可以通过这个方法,知道可用通道的集合
Iterator keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey sk = (SelectionKey) keyIterator.next();
keyIterator.remove();
dealWithSelectionKey(sk);
}
}
}
catch (IOException io)
{}
}

private void dealWithSelectionKey(SelectionKey sk) throws IOException {
if(sk.isReadable())
{
//使用 NIO 读取 Channel中的数据,这个和全局变量sc是一样的,因为只注册了一个SocketChannel
//sc既能写也能读,这边是读
SocketChannel sc = (SocketChannel)sk.channel();

ByteBuffer buff = ByteBuffer.allocate(1024);
String content = "";
while(sc.read(buff) > 0)
{
buff.flip();
content += charset.decode(buff);
}
//若系统发送通知名字已经存在,则需要换个昵称
if(USER_EXIST.equals(content)) {
name = "";
}
System.out.println(content);
sk.interestOps(SelectionKey.OP_READ);
}
}
}



public static void main(String[] args) throws IOException
{
new NioClient().init();
}

}