首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

Java nio实现socket通信遇到的有关问题

2012-01-19 
Java nio实现socket通信遇到的问题新的连接可以正常连接,没有测试连接上限。现在的问题是我想处理从客户端

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

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;public class TestClient {    public static void main(String[] args) {        new MiniClient("localhost", 1982);    }}class MiniClient {    private SocketChannel sc;    private ByteBuffer w_bBuf;    public MiniClient(String host, int port) {        try {            InetSocketAddress remote = new InetSocketAddress(host, port);            sc = SocketChannel.open();            sc.connect(remote);            if(sc.finishConnect()) {                System.out.println("已经与服务器成功建立连接...");            }            while(true) {                if(!sc.isConnected()) {                    System.out.println("已经与服务器失去了连接...");                }                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));                String str = "123";                System.out.println("读入一行数据,开始发送...");                w_bBuf = ByteBuffer.wrap(str.getBytes());                w_bBuf.flip();                sc.write(w_bBuf);                System.out.println("数据发送成功...");                w_bBuf.clear();                try {                    Thread.currentThread().sleep(10000000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        } catch (IOException e) {            // TODO Auto-generated catch block            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();
}
}


public abstract int write(ByteBuffer src)
throws IOException
将字节序列从给定的缓冲区中写入此通道。 

public abstract int read(ByteBuffer dst)
throws IOException
将字节序列从此通道中读入给定的缓冲区。
[解决办法]
首先 你没有任何关闭操作 如果你说的关闭是把程序关闭...这根本不算关闭连接,这个异常是要做处理的 一方强制关闭 另一方做任何动作必然出现IOException 最好在catch里面关闭掉连接
第二个问题
it.remove();换成key.cancel();两个区别很大,这个问题以前我遇到过 当时调试了很长时间看变量信息发现的问题,现在想不太起来了 反正it.remove()后你那个read操作可以一直在
第三个问题
你这程序只能连接一个客户端,如果连接两个就出问题,你是这样设计的话就无视这个问题
第四个问题
客户端你起码给一个退出的信号吧 全部强制结束?
比如
Java code
String str = br.readLine();                if(str==null||str.length()==0)                {                    sc.close();                    break;                }
[解决办法]
探讨

引用:
首先 你没有任何关闭操作 如果你说的关闭是把程序关闭...这根本不算关闭连接,这个异常是要做处理的 一方强制关闭 另一方做任何动作必然出现IOException 最好在catch里面关闭掉连接
第二个问题
it.remove();换成key.cancel();两个区别很大,这个问题以前我遇到过 当时调试了很长时间看变量信息发现的问题,现在想……

热点排行