java用多线程写tcp_JAVA NIO TCP SOCKET 聊天群发(并发多线程写消息篇)(支持中文聊天)...

前面介绍够多了,只是现在添加了中文聊天而已。java.nio.charset里面的东西而已。

不多说了,上代码 . :)

服务器端:MySocketServer.java

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package com.kevin.nio;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.CharBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.nio.charset.CharsetEncoder;

import java.util.Date;

import java.util.Iterator;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.logging.Level;

import java.util.logging.Logger;

/**

*

* @author kevin

*/

public class MySocketServer implements Runnable{

private boolean running;

private Selector selector;

String writeMsg;

SelectionKey ssckey;

ExecutorService exec;

CharsetDecoder decoder;

CharsetEncoder encoder;

Charset charset;

public MySocketServer(){

running=true;

exec=Executors.newCachedThreadPool();

charset=Charset.forName("GB2312");

decoder=charset.newDecoder();

encoder=charset.newEncoder();

}

public void init(){

try {

selector = Selector.open();

ServerSocketChannel ssc = ServerSocketChannel.open();

ssc.configureBlocking(false);

ssc.socket().bind(new InetSocketAddress(2345));

ssckey=ssc.register(selector, SelectionKey.OP_ACCEPT);

System.out.println("server is starting..."+new Date());

} catch (IOException ex) {

Logger.getLogger(MySocketServer.class.getName()).log(Level.SEVERE, null, ex);

}

}

public static void main(String[] args){

MySocketServer server=new MySocketServer();

new Thread(server).start();

}

public void execute(){

try {

while(running){

int num=selector.select();

if(num>0){

Iterator it=selector.selectedKeys().iterator();

while(it.hasNext()){

SelectionKey key=it.next();

it.remove();

if(!key.isValid()) continue;

if(key.isAcceptable()){

System.out.println("isAcceptable");

getConn(key);

}

else if(key.isReadable()){

System.out.println("isReadable");

readMsg(key);

}

else if(key.isValid()&&key.isWritable()){

if(writeMsg!=null){

System.out.println("isWritable");

writeMsg(key);

}

}

else break;

}

}

Thread.yield();

}

} catch (IOException ex) {

Logger.getLogger(MySocketServer.class.getName()).log(Level.SEVERE, null, ex);

}

}

private void getConn(SelectionKey key) throws IOException {

ServerSocketChannel ssc=(ServerSocketChannel)key.channel();

SocketChannel sc=ssc.accept();

sc.configureBlocking(false);

sc.register(selector, SelectionKey.OP_READ);

//sc.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);

System.out.println("build connection :"+sc.socket().getRemoteSocketAddress());

}

private void readMsg(SelectionKey key) throws IOException {

StringBuffer sb=new StringBuffer();

SocketChannel sc=(SocketChannel)key.channel();

System.out.print(sc.socket().getRemoteSocketAddress()+" ");

ByteBuffer buffer=ByteBuffer.allocate(1024);

buffer.clear();

int len=0;

while((len=sc.read(buffer))>0){

buffer.flip();

CharBuffer cb=decoder.decode(buffer);

sb.append(new String(cb.array()));

buffer.clear();

}

if(sb.length()>0) System.out.println("get from client:"+sb.toString());

if(sb.toString().trim().toLowerCase().equals("quit")){

sc.write(ByteBuffer.wrap("BYE".getBytes()));

System.out.println("client is closed."+sc.socket().getRemoteSocketAddress());

key.cancel();

sc.close();

sc.socket().close();

}

else{

String toMsg=sc.socket().getRemoteSocketAddress()+ "said:"+sb.toString();

System.out.println(toMsg);

Iterator it=key.selector().keys().iterator();

while(it.hasNext()){

SelectionKey skey=it.next();

if(skey!=key&&skey!=ssckey){

MyWriter myWriter=new MyWriter(skey,toMsg);

exec.execute(myWriter);

}

}

/*

key.attach(toMsg);

key.interestOps(key.interestOps()|SelectionKey.OP_WRITE);

*

*/

/*

Iterator it=key.selector().keys().iterator();

while(it.hasNext()){

SelectionKey skey=it.next();

if(skey!=key&&skey!=ssckey){

if(skey.attachment()!=null){

String str=(String) skey.attachment();

skey.attach(str+toMsg);

}else{

skey.attach(toMsg);

}

skey.interestOps(skey.interestOps()|SelectionKey.OP_WRITE);

}

}

selector.wakeup();//可有可无

*

*/

}

}

class MyWriter implements Runnable{

SelectionKey key;

String msg;

public MyWriter(SelectionKey key,String msg){

this.key=key;

this.msg=msg;

}

public void run() {

try {

SocketChannel client = (SocketChannel) key.channel();

ByteBuffer bb=encoder.encode(CharBuffer.wrap(msg));

long len=0;

while((len=client.write(bb))>0);

} catch (IOException ex) {

Logger.getLogger(MyWriter.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

public void run() {

init();

execute();

}

private void writeMsg(SelectionKey key) throws IOException {

System.out.println("++++enter write+++");

SocketChannel sc=(SocketChannel) key.channel();

String str=(String) key.attachment();

sc.write(ByteBuffer.wrap(str.getBytes()));

key.interestOps(SelectionKey.OP_READ);

}

}

客户端:MySocketClient.java

/*

* To change this template, choose Tools | Templates

* and open the template in the editor.

*/

package com.kevin.nio;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.CharBuffer;

import java.nio.channels.Selector;

import java.nio.channels.SocketChannel;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.nio.charset.CharsetEncoder;

import java.util.logging.Level;

import java.util.logging.Logger;

import java.util.Currency.*;

/**

*

* @author kevin

*/

public class MySocketClient implements Runnable{

Selector selector;

boolean running;

SocketChannel sc;

CharsetDecoder decoder;

CharsetEncoder encoder;

public MySocketClient(){

running=true;

Charset charset=Charset.forName("GB2312");

decoder=charset.newDecoder();

encoder=charset.newEncoder();

}

public void init() {

try {

sc = SocketChannel.open();

sc.configureBlocking(false);

sc.connect(new InetSocketAddress("localhost", 2345));

} catch (IOException ex) {

Logger.getLogger(MySocketClient.class.getName()).log(Level.SEVERE, null, ex);

}

}

public static void main(String[] args){

MySocketClient client=new MySocketClient();

new Thread(client).start();

}

public void execute(){

int num=0;

try {

while (!sc.finishConnect()) {

}

} catch (IOException ex) {

Logger.getLogger(MySocketClient.class.getName()).log(Level.SEVERE, null, ex);

}

ReadKeyBoard rkb=new ReadKeyBoard();

new Thread(rkb).start();

while(running){

try {

ByteBuffer buffer=ByteBuffer.allocate(1024);

buffer.clear();

StringBuffer sb=new StringBuffer();

Thread.sleep(500);

while((num=sc.read(buffer))>0){

buffer.flip();

System.out.println("receiving..."+num);

CharBuffer cb=decoder.decode(buffer);

sb.append(new String(cb.array()));

buffer.clear();

}

if(sb.length()>0) System.out.println(sb.toString());

if(sb.toString().toLowerCase().trim().equals("bye")){

System.out.println("closed....");

sc.close();

sc.socket().close();

rkb.close();

running=false;

}

} catch (InterruptedException ex) {

Logger.getLogger(MySocketClient.class.getName()).log(Level.SEVERE, null, ex);

} catch (IOException ex) {

Logger.getLogger(MySocketClient.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

public void run() {

init();

execute();

}

class ReadKeyBoard implements Runnable{

boolean running2=true;

public ReadKeyBoard(){

}

public void close(){

running2=false;

}

public void run() {

BufferedReader reader=null;

try {

reader = new BufferedReader(new InputStreamReader(System.in, "GB2312"));

} catch (UnsupportedEncodingException ex) {

Logger.getLogger(MySocketClient.class.getName()).log(Level.SEVERE, null, ex);

}

while(running2){

try {

System.out.println("enter some commands:");

String str = reader.readLine();

ByteBuffer bb=encoder.encode(CharBuffer.wrap(str));

System.out.println("get command:"+str);

long len=0;

while((len=sc.write(bb))>0);

} catch (IOException ex) {

Logger.getLogger(ReadKeyBoard.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

}

}

注意点:1.

long len=0;

while((len=sc.write(bb))>0);

这里只是防止buffer 太大,一次发不完。

2. reader = new BufferedReader(new InputStreamReader(System.in, "GB2312"));这里是从console 读取中文。

到这里,所有的功能已经完成。

打完收工,改其他的方面。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值