서버 측에서 ServerSocket
채널 (NIO)을 사용하고 있습니다. 내 질문은, 소켓 채널이 클라이언트에 데이터를 쓰기 전에 쓰기가 가능한지 여부를 확인하지 않으면 어떻게 될까요? 나는 채널이 준비되었는지 확인하지 않고 잘 작동하는 서버 프로그램을 테스트했다.데이터를 쓰기 전에 채널 isWritable()을 검사해야하는 이유
public class SelectorExample {
public static void main (String [] args)
throws IOException {
// Get selector
Selector selector = Selector.open();
System.out.println("Selector open: " + selector.isOpen());
// Get server socket channel and register with selector
ServerSocketChannel serverSocket = ServerSocketChannel.open();
//serverSocket.setOption(StandardSocketOptions.SO_REUSEADDR, true);
InetSocketAddress hostAddress = new InetSocketAddress("localhost", 5454);
serverSocket.socket().bind(hostAddress,0);
serverSocket.configureBlocking(false);
int ops = serverSocket.validOps();
SelectionKey selectKy = serverSocket.register(selector, ops, null);
for (;;) {
System.out.println("Waiting for select...");
int noOfKeys = selector.select();
Set selectedKeys = selector.selectedKeys();
Iterator iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey ky = (SelectionKey)iter.next();
++count;
if (ky.isAcceptable()) {
// Accept the new client connection
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
// Add the new connection to the selector
client.register(selector, SelectionKey.OP_READ);
System.out.println("["+new java.sql.Timestamp(System.currentTimeMillis())+"]"+"Accepted new connection from client: " + client);
}
else if (ky.isReadable()) {
// Read the data from client
SocketChannel client = (SocketChannel) ky.channel();
ByteBuffer buffer = ByteBuffer.allocate(2048);
int i =client.read(buffer);
String output = new String(buffer.array());
System.out.println("Message read from client: " + output);
output =output.trim();
output=output+"\r\n";
//*********write message here******
byte[] a=output.getBytes();
ByteBuffer bb=ByteBuffer.wrap(a);
client.write(bb);
buffer.clear();
System.out.println(" Sent Message ");
if (i == -1) {
client.close();
System.out.println("Client messages are complete; close.");
}
} // end if (ky...)
//countkey++;
iter.remove();
} // end while loop
} // end for loop
}
은}
'ServerSocket' 또는'ServerSocketChannel' 안의'isWriteable()'메소드를 보지 않아요 –
이것은 SelectionKey 클래스에 있습니다 –
SocketChannel이 블로킹 모드이면 write를위한 호출은 항상 모든 데이터를 씁니다. 그렇게하기를 기다릴 수도 있습니다. 채널이 비 블로킹 모드에 있으면 소켓의 출력 버퍼에서 사용할 수있는만큼의 바이트 만 씁니다. –