서버와 클라이언트 부분을 NIO 방식으로 짜서 


안드로이드 클라이언트와 자바 서버 소스를 구현했고 연결이 되는 것을 확인하였습니다.


그러나 Editbox의 데이터를 얻어 버퍼에 넣고 서버채널에 write하여 서버로 데이터를 전송하는 것과


서버로부터 write된 정보를 read해서 textview에 뿌려주는 것이 잘안되고 있습니다. 


Receive rt = new Receive();

new Thread(rt).start();

startWriter()

를 살리게 되면 동작이 안되고 어플이 뻗어 버립니다.


원인이 무엇인지 가르쳐주세요


<자바 Sever 부분>

import java.io.IOException;

import java.net.InetAddress;

import java.net.InetSocketAddress;

import java.net.Socket;

import java.net.SocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.util.*;


public class EchoServer {

    private InetAddress addr;

    private int port;

    private Selector selector;

    private Map<SocketChannel,List<byte[]>> dataMap;


    public EchoServer(InetAddress addr, int port) throws IOException {

        this.addr = addr;

        this.port = port;

        dataMap = new HashMap<SocketChannel,List<byte[]>>();

        startServer();

    }


    private void startServer() throws IOException {

        // create selector and channel

        this.selector = Selector.open();

        ServerSocketChannel serverChannel = ServerSocketChannel.open();

        serverChannel.configureBlocking(false);


        // bind to port

        InetSocketAddress listenAddr = new InetSocketAddress(this.addr, this.port);

        serverChannel.socket().bind(listenAddr);

        serverChannel.register(this.selector, SelectionKey.OP_ACCEPT);


        log("Echo server ready. Ctrl-C to stop.");


        // processing

        while (true) {

            // wait for events

            this.selector.select();


            // wakeup to work on selected keys

            Iterator<SelectionKey> keys = this.selector.selectedKeys().iterator();

            while (keys.hasNext()) {

                SelectionKey key = (SelectionKey) keys.next();


                // this is necessary to prevent the same key from coming up 

                // again the next time around.

                keys.remove();


                if (! key.isValid()) {

                    continue;

                }


                if (key.isAcceptable()) {

                    this.accept(key);

                }

                else if (key.isReadable()) {

                    this.read(key);

                }

                else if (key.isWritable()) {

                    this.write(key);

                }

            }

        }

    }


    private void accept(SelectionKey key) throws IOException {

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

        SocketChannel channel = serverChannel.accept();

        channel.configureBlocking(false);


        // write welcome message

        channel.write(ByteBuffer.wrap("Welcome, this is the echo server\r\n".getBytes("US-ASCII")));


        Socket socket = channel.socket();

        SocketAddress remoteAddr = socket.getRemoteSocketAddress();

        log("Connected to: " + remoteAddr);


        // register channel with selector for further IO

        dataMap.put(channel, new ArrayList<byte[]>());

        channel.register(this.selector, SelectionKey.OP_READ);

    }


    private void read(SelectionKey key) throws IOException {

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


        ByteBuffer buffer = ByteBuffer.allocate(8192);

        int numRead = -1;

        try {

            numRead = channel.read(buffer);

            

        }

        catch (IOException e) {

            e.printStackTrace();

        }


        if (numRead == -1) {

            this.dataMap.remove(channel);

            Socket socket = channel.socket();

            SocketAddress remoteAddr = socket.getRemoteSocketAddress();

            log("Connection closed by client: " + remoteAddr);

            channel.close();

            key.cancel();

            return;

        }

        else {

        while(buffer.hasRemaining()){

        log("data transmited by client: " + buffer.getChar());

        }

        }


        byte[] data = new byte[numRead];

        System.arraycopy(buffer.array(), 0, data, 0, numRead);

        log("Got: " + new String(data, "US-ASCII"));


        // write back to client

        doEcho(key, data);

    }


    private void write(SelectionKey key) throws IOException {

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

        List<byte[]> pendingData = this.dataMap.get(channel);

        Iterator<byte[]> items = pendingData.iterator();

        while (items.hasNext()) {

            byte[] item = items.next();

            items.remove();

            channel.write(ByteBuffer.wrap(item));

        }

        key.interestOps(SelectionKey.OP_READ);

    }


    private void doEcho(SelectionKey key, byte[] data) {

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

        List<byte[]> pendingData = this.dataMap.get(channel);

        pendingData.add(data);

        key.interestOps(SelectionKey.OP_WRITE);

    }


    private static void log(String s) {

        System.out.println(s);

    }


    public static void main(String[] args) throws Exception {

        new EchoServer(null, 9999);

    }

}


<안드로이드 client 부분>

package com.example.android_nio_client;


import java.io.IOException;

import java.io.ObjectOutputStream;

import java.io.PrintWriter;

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.SocketChannel;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.util.Iterator;

import java.util.Scanner;


import android.os.AsyncTask;

import android.os.Bundle;

import android.printservice.PrintService;

import android.app.Activity;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.TextView;


public class MainActivity extends Activity {


static Selector selector = null;

private SocketChannel sc = null;

public TextView tv = null;

public EditText et = null;

public Button btn = null;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv = (TextView)findViewById(R.id.textView1);

et = (EditText)findViewById(R.id.editText1);

btn = (Button)findViewById(R.id.button1);

new ConnectTask().execute(null, null, null);

Receive rt = new Receive();

new Thread(rt).start();

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

startWriter();

}

});

}

public void startWriter(){

ByteBuffer buffer = ByteBuffer.allocateDirect(8192);

try {

while(true){

// Scanner scanner = new Scanner(System.in);

// String message = scanner.next();

String message = et.getText().toString();

buffer.clear();

buffer.put(message.getBytes());

buffer.flip();

sc.write(buffer);

}

} catch (IOException e) {

}finally{

clearBuffer(buffer);

}

}

static void clearBuffer(ByteBuffer buffer){

if(buffer != null){

buffer.clear();

buffer = null;

}

}

class Receive implements Runnable {

private Charset charset = null;

private CharsetDecoder decoder = null;

public void run(){

charset = Charset.forName("EUC-KR");

decoder = charset.newDecoder();

try {

while(true){

MainActivity.selector.select();

Iterator<SelectionKey> it = MainActivity.selector.selectedKeys().iterator();

while(it.hasNext()){

SelectionKey key = (SelectionKey)it.next();

if(key.isReadable()){

read(key);

}else{}

it.remove();

}

}

} catch (IOException e) {

}

}

private void read(SelectionKey key){

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

ByteBuffer buffer = ByteBuffer.allocateDirect(8192);

int nbyte = 0;

try {

nbyte = sc.read(buffer);

buffer.flip();

String data = decoder.decode(buffer).toString();

// System.out.println("Receive Message - " + data);

while(buffer.hasRemaining()){

tv.setText("Receive Message - " + data);

}

MainActivity.clearBuffer(buffer);

} catch (IOException e) {

// TODO Auto-generated catch block

try {

sc.close();

} catch (IOException e1) {

}

}

}

}

private class ConnectTask extends AsyncTask<Void, Void, Void>{


@Override

protected Void doInBackground(Void... params) {

// TODO Auto-generated method stub

try {

selector = Selector.open();

sc = SocketChannel.open(new InetSocketAddress("192.168.0.56", 9999));

sc.configureBlocking(false);

sc.register(selector, SelectionKey.OP_READ);

tv.setText("서버에 접속이 되었습니다.");

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

}

}