日期:2014-05-20  浏览次数:20821 次

Java nio实现socket通信遇到的问题
新的连接可以正常连接,没有测试连接上限。
现在的问题是我想处理从客户端发送消息,服务端接收消息并发给客户端。
现在在服务端接收不到客户端发来的消息怎么办?

server端代码:
Java code
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Calendar;
import java.util.Iterator;


public class TestServer {
    public static void main(String[] args) {
        new EchoServer(1982);
    }
}

class EchoServer implements Runnable {
    //要监听的端口号
    private int port;
    //生成一个信号监视器
    private Selector s;
    //读缓冲区
    private ByteBuffer r_bBuf = ByteBuffer.allocate(1024);
    
    public EchoServer(int port) {
        this.port = port;
        try {
            s = Selector.open();
        } catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(this).start();
    }

    @Override
    public void run() {
        try {
            //生成一个ServerScoket通道的实例对象,用于侦听可能发生的IO事件
            ServerSocketChannel ssc = ServerSocketChannel.open();
            //将该通道设置为异步方式
            ssc.configureBlocking(false);
            //绑定到一个指定的端口
            ssc.socket().bind(new InetSocketAddress(port));
            //注册特定类型的事件到信号监视器上
            ssc.register(s, SelectionKey.OP_ACCEPT);
            System.out.println("The server has been launched...");
            while(true) {
                //将会阻塞执行,直到有事件发生
                System.out.println("监听新事件...");
                s.select();
                Iterator<SelectionKey> it = s.selectedKeys().iterator();
                while(it.hasNext()) {
                    SelectionKey key = it.next();
                    //key定义了四种不同形式的操作
                    switch(key.readyOps()) {
                    case SelectionKey.OP_ACCEPT :
                        dealwithAccept(key);
                        break;
                    case SelectionKey.OP_CONNECT :
                        break;
                    case SelectionKey.OP_READ :
                        break;
                    case SelectionKey.OP_WRITE :
                        dealwithRead(key);
                        break;
                    }
                    //处理结束后移除当前事件,以免重复处理
                    it.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //处理接收连接的事件
    private void dealwithAccept(SelectionKey key) {
        try {
            System.out.println("deal with new accept...");
            ServerSocketChannel server = (ServerSocketChannel)key.channel();
            SocketChannel sc = server.accept();
            sc.configureBlocking(false);
            //注册读事件
            sc.register(s, SelectionKey.OP_WRITE);
            System.out.println("deal with new accept2...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //处理客户端发来的消息,处理读事件
    private void dealwithRead(SelectionKey key) {
        try {
            SocketChannel sc = (SocketChannel)key.channel();
            System.out.println("读入数据");
            r_bBuf.clear();
            System.out.println(r_bBuf.position());
            sc.write(r_bBuf);
            System.out.println(r_bBuf.position());
            r_bBuf.flip();
            System.out.println(r_bBuf.asCharBuffer().toString());
            r_bBuf.clear();
            System.out.println("处理完毕...");
            try {
                Thread.currentThread().sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private String getCurrentTime() {
        return Calendar.getInstance().toString();
    }
}


client端代码
Java code