java NIO 学习 聊天室程序 (3)

LoginCmd:

package com.tcl.chat.command;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

import com.tcl.chat.ChatServer;
import com.tcl.chat.Member;
import com.tcl.chat.utils.LogUtil;

public class LoginCmd extends Command {
private static ByteBuffer ERROR = ByteBuffer
.wrap("Error username and password".getBytes());
private static ByteBuffer SUCCESS = ByteBuffer.wrap("Login success"
.getBytes());

@Override
public void handleCmd(SelectionKey key, ChatServer server, String[] args)
throws IOException {
// TODO Auto-generated method stub
LogUtil.i("Login CMD :");
SocketChannel sc = (SocketChannel) key.channel();
if (args.length == 3) {
String username = args[1];
String password = args[2];
Member mb = server.getMemberStorage().get(username);
if (mb != null) {

boolean flag = mb.login(username, password);
if (flag) {
sc.write(SUCCESS);
SUCCESS.flip();
server.getLoginMemberMap() //add to login map
.put(sc.socket().getRemoteSocketAddress()
.toString(), mb);
return;
}
}
}
sc.write(ERROR);
ERROR.flip();
return;
}
}

QuitCmd

package com.tcl.chat.command;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

import com.tcl.chat.ChatServer;

public class QuitCmd extends Command {
private static ByteBuffer BYE = ByteBuffer.wrap("bye".getBytes());
@Override
public void handleCmd(SelectionKey key, ChatServer server,String[] args) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
sc.write(BYE);
BYE.flip();
System.out.println("Say goodbye");
String address = sc.socket().getRemoteSocketAddress()
.toString();
System.out.println("close: " + address);
server.getChannelMap().remove(address);
server.getLoginMemberMap().remove(address);
sc.close();
key.cancel();//cancel the key
}

}

再贴一下客户端的程序:

package com.tcl.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.tcl.chat.impl.ChatRecordStorageImpl;

public class ChatClient implements Runnable{
private Logger log = Logger.getLogger(ChatClient.class.getName());
SocketChannel mChannel;
boolean bRunFlag = true;
private boolean bIsInit = false;
String mHostname;
int mPort;

private ChatRecordStorage mChatStorage = new ChatRecordStorageImpl();

public ChatClient(String host,int port){
mHostname = host;
mPort = port;
}
private static final int TRY_TIMES = 3;
public void init() throws IOException{
mChannel = SocketChannel.open();
mChannel.configureBlocking(false);
mChannel.connect(new InetSocketAddress(mHostname,mPort));
int i = 0;
boolean error = false;
while (!mChannel.finishConnect() ) {
if (i >= TRY_TIMES) {
error = true;
break;
}
i++;
//
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (error) {
throw new IOException("连接错误,稍后再试");
}
bIsInit = true;
}

@Override
public void run() {
try {
init();

} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
if (!bIsInit) {
throw new RuntimeException("not init");
}
ByteBuffer buffer = ByteBuffer.allocate(1024);
KeyBordReader kbr = new KeyBordReader();
new Thread(kbr).start();//阻塞方式的读

while (bRunFlag) {
buffer.clear();
StringBuffer sb = new StringBuffer();
int num;
try {
Thread.sleep(500);
while((num = mChannel.read(buffer)) > 0){
sb.append(new String(buffer.array(),0,num));
buffer.clear();
}
if (sb.length() > 0 ) {
log.log(Level.INFO,"Client Recerive:" + sb.toString());
}
if (sb.toString().toLowerCase().trim().equals("bye")) {
mChannel.close();
kbr.close();
bRunFlag = false;
System.exit(0); //退出
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
public static void main(String[] args) {
int port = 10003;
new Thread(new ChatClient("localhost", port)).start();
}

class KeyBordReader implements Runnable{
public KeyBordReader(){

}
private boolean bRunFlag = true;
public void close(){
bRunFlag = false;
}
@Override
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (this.bRunFlag) {
//System.out.println(TIP);
try {
String str = reader.readLine().trim();
if (str == null) {
continue;
}
if (!str.startsWith("@")) {
System.out.println("must begin with @");
continue;
}else if (str.equals("@help")) {
System.out.println(TIP);
}else if (str.equals("@exit")) {
System.exit(0);
}
mChannel.write(ByteBuffer.wrap(str.getBytes()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

}
private static String TIP = ""
+ "@pub to send public message\n"
+ "@xxx to send private message \n"
+ "@exit to exit client\n"
+ "@quit to quit from server\n"
+ "@listmember to list members";

}


贴起来好费劲,不如直接上传源码。。。。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值