ServerSocketChannel类是抽象的,并不能直接被实例化,但是API中提供了public static ServerSocketChannel open()
方法来创建ServerSocketChannel类的实例。open()
方法是静态的,目的是为了打开服务器套接字通道。新通道的套接字最初是未绑定的;可以在连接之前,必须通过它的某个套接字的bind()
方法将其绑定到具体的地址。
可以调用public abstract ServerSocket socket()
方法来返回ServerSocket类的对象,然后与客户端套接字通信。
public final void close()
方法的作用是关闭此通道。如果已经关闭通道,则此方法立即返回。否则,他会将该通道标记为已关闭,然后调用implCloseChannel()
方法完成关闭操作。
package book.chapter5_7;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
public class Test1_Server1 {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress("localhost", 8888));
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] charArr = new char[1024];
int readLength = inputStreamReader.read(charArr);
while (readLength != -1) {
String newString = new String(charArr, 0, readLength);
System.out.println(newString);
readLength = inputStreamReader.read(charArr);
}
inputStreamReader.close();
inputStream.close();
socket.close();
serverSocket.close();
serverSocketChannel.close();
}
}
代码中,我们使用了
serverSocket.bind(new InetSocketAddress("localhost", 8888));
将ServerSocket类绑定到指定的地址,而ServerSocketChannel类也有`bind()`方法,两者达到的效果是一样的,只需要使用其中之一即可。
serverSocketChannel.bind(new InetSocketAddress("localhost", 8888));
其实,不使用ServerSocketChannel类,单纯的使用ServerSocket类和Socket类也能实现服务端和客户端通信的目的。但是主要注意的是不使用ServerSocketChannel类是无法实现IO的多路服用的。至于ServerSocketChannel类是如何实现多路复用的,我们后文再讲。