我可以从io客户端发送数据(仅使用套接字而不是套接字通道),但无法从nio服务器发送数据(使用套接字通道)。有什么问题?
通过I / O流和bytebuffer进行读/写的方式有区别吗?
public class Server {
// this is equivalent to the server socket in the non nio world
ServerSocketChannel serverSocketChannel;
// this is the multiplexer which multiplexes the messages received from
// different clients
Selector selector;
public Server() {
try {
// get a selector
selector = Selector.open();
// get a server socket channel
serverSocketChannel = ServerSocketChannel.open();
// we force the socket to be Non-blocking.
// if it is set to "true" then this socket acts as a normal
// (blocking) server socket
serverSocketChannel.configureBlocking(false);
// port and ip address where the server listens for connections
InetSocketAddress add = new InetSocketAddress(
InetAddress.getLocalHost(), 9999);
// bind the server socket to the ip/port
serverSocketChannel.socket().bind(add);
// register the serverSocketChannel (for incoming connection events)
// to the selector.
// The "SelectionKey.OP_ACCEPT" parameter tells the selector that
// this serverSocketChannel registers
// itself for incoming (acceptable) connections
SelectionKey key = serverSocketChannel.register(selector,
SelectionKey.OP_ACCEPT);
System.out.println("serverSocketChannel's registered key is : "
+ key.channel().toString());
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.startListening();
}
private void startListening() {
System.out.println("Server is listening on: "
+ serverSocketChannel.socket().getInetAddress()
.getHostAddress() + ":"
+ serverSocketChannel.socket().getLocalPort());
while (true) {
try {
// this line blocks until some events has occurred in the
// underlying socket
selector.select();
// get the selected keys set
Set selectedKeys = selector.selectedKeys();
Iterator iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
// a client has asked for a new connection
if (key.isAcceptable()) {
// only ServerSocketsChannels registered for OP_ACCEPT
// are excepted to receive an
// "acceptable" key
System.out.println("Key ready to perform accept() : "
+ key.channel().toString());
// as usual the accept returns the plain socket towards
// the client
SocketChannel client = serverSocketChannel.accept();
// set the client socket to be non blocking
client.configureBlocking(false);
// register the client socket with the same selector to
// which we have registered the
// serverSocketChannel
client.register(selector, SelectionKey.OP_READ);
// client.register(selector, SelectionKey.OP_WRITE);
continue;
}
// the client has sent something to be read by this server
if (key.isReadable()) {
System.out.println("Key ready to perform read() : "
+ key.channel().toString());
// get the underlying socket
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer bb = ByteBuffer.allocate(10000);
// read the msg sent by the client
client.read(bb);
// display the message
bb.flip();
byte[] array = new byte[bb.limit()];
bb.get(array);
System.out.println(new String(array));
// send the message
ByteBuffer bb1 = ByteBuffer.allocate(10000);
String s = "server data";
byte[] array1 = new byte[bb1.limit()];
array1 = s.getBytes();
bb1.put(array1);
client.write(bb1);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
void write() {
}
}
public class Client {
static String IP = "192.168.123.105"; // server IP address
public static void main(String[] args) throws UnknownHostException,
IOException {
// TODO Auto-generated method stub
String msg;
Socket socket = new Socket(IP, 9999);
System.out.println("client: complete making socket");
Scanner scan = new Scanner(System.in);
System.out.println("client: input data to send");
while (true) {
// read
System.out.print(">>>");
msg = scan.nextLine();
OutputStream out = socket.getOutputStream();
DataOutputStream dou = new DataOutputStream(out);
dou.writeUTF(msg);
// write from server
InputStream in = socket.getInputStream();
DataInputStream din = new DataInputStream(in);
String remsg = din.readUTF();
System.out.println("client: data from server" + remsg);
if (remsg.equalsIgnoreCase("END")) {
System.out.println("SOCKET END");
socket.close();
break;
}
}
}
}
答案 0 :(得分:-1)
我解决了问题!
这是关于如何从客户端
中读取输入流的问题我更改了部分客户端代码
这
InputStream in = socket.getInputStream();
DataInputStream din = new DataInputStream(in);
String remsg = din.readUTF();
System.out.println("client: data from server" + remsg);
到
ByteBuffer bb1 = ByteBuffer.allocate(10000);
byte[] array1 = new byte[bb1.limit()];
InputStream in = socket.getInputStream();
in.read(array1);
String remsg=new String(array1);
并在服务器代码中添加了OP_WRITE / isWritable(),如下所示
if (key.isReadable()) {
System.out.println("Key ready to perform read() : "
+ key.channel().toString());
// get the underlying socket
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer bb = ByteBuffer.allocate(1024);
// read the msg sent by the client
client.read(bb);
// display the message
bb.flip();
byte[] array = new byte[bb.limit()];
bb.get(array);
System.out.println(new String(array));
client.register(selector, SelectionKey.OP_WRITE);
continue;
}
if(key.isWritable()){
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer bb1 = ByteBuffer.allocate(10000);
String s = "server data";
byte[] array1 = new byte[bb1.limit()];
array1 = s.getBytes();
bb1.put(array1);
bb1.flip();
client.write(bb1);
}