Java 具有NIO通道的简单客户机-服务器程序
解决 如果有人感兴趣,我可以用正确的数据编辑这篇文章。请留下评论 作为我的任务,我必须使用非阻塞通道和选择器创建一个简单的服务器和一个客户端。 基本上,它要么响应客户机编写的消息,要么添加客户机提供的两个数字 我的问题是,我在服务器将要回显消息的位置出错。 我已经检查了msg是否进入writeResponse方法,它确实如此。所以问题就从这里开始 提前谢谢大家 我得到的错误:Java 具有NIO通道的简单客户机-服务器程序,java,buffer,echo,nio,socketchannel,Java,Buffer,Echo,Nio,Socketchannel,解决 如果有人感兴趣,我可以用正确的数据编辑这篇文章。请留下评论 作为我的任务,我必须使用非阻塞通道和选择器创建一个简单的服务器和一个客户端。 基本上,它要么响应客户机编写的消息,要么添加客户机提供的两个数字 我的问题是,我在服务器将要回显消息的位置出错。 我已经检查了msg是否进入writeResponse方法,它确实如此。所以问题就从这里开始 提前谢谢大家 我得到的错误: java.io.IOException: An existing connection was forcibly
java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218)
at sun.nio.ch.IOUtil.read(IOUtil.java:191)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:359)
at SimpleServer.serviceRequest(SimpleServer.java:89)
at SimpleServer.serviceConnections(SimpleServer.java:61)
at SimpleServer.<init>(SimpleServer.java:35)
at SimpleServer.main(SimpleServer.java:141)
如果read返回-1,则不表示“服务器没有响应”。这意味着对等方已经关闭了连接,您也应该这样做。相反,您根本没有关闭它,因此操作系统会重置,因此您的服务器会出现此异常。谢谢您的回答,但我已经修复了我的程序。如果有人感兴趣,这个错误是由以下几个问题引起的:1。加法值应转换为double,而不是int 2。缺少缓冲读取器3。Charset.defaultCharset.decodebbuf.toString;应该使用,而不是我所做的附加。你能用正确的版本编辑你的文章吗??
public class SimpleServer {
private ServerSocketChannel ssc = null; //for multiplexing
private Selector selector = null; //monitors channels
private static Charset charset = Charset.defaultCharset();//encoding
private static final int BSIZE = 1024;//buffer size
private ByteBuffer bbuf = ByteBuffer.allocate(BSIZE);
private StringBuffer reqString = new StringBuffer();
public SimpleServer(String host, int port) {
try {
ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.socket().bind(new InetSocketAddress(host, port));
selector = Selector.open(); //selector initiation
ssc.register(selector, SelectionKey.OP_ACCEPT); //registering communication channel
} catch(Exception exc) {
exc.printStackTrace();
System.out.println(1);
}
System.out.println("Server started and is ready for requests");
serviceConnections();
}//constructor
private void serviceConnections() {
boolean serverIsRunning = true;
while(serverIsRunning) {
try {
selector.select();//waits for answer from selector
Set<SelectionKey> keys = selector.selectedKeys(); //set of keys
Iterator<SelectionKey> iter = keys.iterator(); //iterration throught set of keys
while(iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next(); //obtain key
iter.remove(); //remove, because we'd get it again
if(key.isAcceptable()) {
SocketChannel cc = ssc.accept();//obtaining channel for communication
cc.configureBlocking(false);
cc.register(selector, SelectionKey.OP_READ); //registering selector for monitoring
continue;
}
if(key.isReadable()) { //channel with readable data
SocketChannel cc = (SocketChannel) key.channel();
serviceRequest(cc);
continue;
}
}//while loop
} catch(Exception exc) {
exc.printStackTrace();
continue;
}
}//outer while loop
}//serviceCconnection method
private void serviceRequest(SocketChannel sc) {
if(!sc.isOpen()) return;
reqString.setLength(0);
bbuf.clear();
try {
readLoop:
while (true) {
int n = sc.read(bbuf);
if(n > 0) {
bbuf.flip();//set limit, return to beginning
CharBuffer cbuf = charset.decode(bbuf);
while(cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break readLoop;
reqString.append(c);
}
}
}//while loop
String[] req = reqString.toString().split(" ");
String cmd = req[0];
if (cmd.equals("bye")) {
sc.close();
sc.socket().close();
}
else if(cmd.equals("echo"))
writeResp(sc, reqString.toString());
else if(cmd.equals("add"))
writeResp(sc, Integer.parseInt(req[1]),Integer.parseInt( req[2]));
} catch (Exception exc) {
exc.printStackTrace();
try { sc.close();
sc.socket().close();
} catch (Exception e) {}
}
}//serviceRequest
//overloaded methods
public void writeResp(SocketChannel sc, String msg) throws IOException {
System.out.println(msg);
ByteBuffer cbuf = charset.encode(CharBuffer.wrap(msg));
cbuf = ByteBuffer.allocate(1024);
cbuf.put(msg.getBytes());
cbuf.rewind();
sc.write(cbuf);
}//writeResp method
public void writeResp(SocketChannel sc, int i, int j) throws IOException, NumberFormatException {
int ans = i + j;
String resp = Integer.toString(ans);
ByteBuffer cbuf = charset.encode(CharBuffer.wrap(resp));
sc.write(cbuf);
}//write Resp method
public static void main(String[] args) {
try {
String host = "localhost";
int port = 9998;
new SimpleServer(host, port);
} catch(Exception exc) {
exc.printStackTrace();
System.out.println(1);
}
}//main
}//class
public class SimpleClient {
private SocketChannel sc;
private static Charset charset;
private StringBuffer reqString = new StringBuffer();
private ByteBuffer bb;
String msg;
public SimpleClient(String host, int port) throws IOException, InterruptedException {
try {
sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(host, port));
System.out.println("Connecting to the server...");
while(!sc.finishConnect()) {
System.out.println("Connection is being established...");
}
} catch (IOException exc) {
System.out.println("IO exception");
System.exit(1);
}
System.out.println("Connection Established!");
makeRequest("echo Test input stream\n");
Thread.sleep(500);
readRequest();
}//constructor
private void makeRequest(String req) throws IOException {
System.out.println("Request: " + req);
bb = ByteBuffer.allocate(1024);
bb.put(req.getBytes());
bb.rewind();
sc.write(bb);
}//makeRequest method
public void readRequest() throws IOException, InterruptedException {
reqString.setLength(0);
bb.clear();
try {
readLoop:
while (true) {
bb.clear();
int readBytes = sc.read(bb);
if(readBytes == 0){
System.out.println("waiting for data");
continue;
}
else if(readBytes == -1) {
System.out.println("Server not responding");
break;
}
else {
bb.flip();
CharBuffer cbuf = charset.decode(bb);
while(cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break readLoop;
reqString.append(c);
}
}
}//while loop
System.out.println(reqString.toString());
} catch( Exception exc) {//while loop
exc.printStackTrace();
}
}//readRequest method
public static void main(String[] args) {
try {
new SimpleClient("localhost", 9998);
}catch (IOException exc) {
exc.printStackTrace();
}catch(InterruptedException exc) {
exc.printStackTrace();
}
}//main method
}//class