java.net.ServerSocket:服务器应用程序使用该类来获取端口并监听客户端请求,ServerSocket 有四个构造函数
- ServerSocket(int port):尝试创建绑定到指定端口的服务器套接字。如果端口已被另一个应用程序绑定,则会发生异常
- ServerSocket(int port, int backlog):backlog 参数指定要在等待队列中存储的传入客户端的数量
- ServerSocket(int port, int backlog, InetAddress address):InetAddress 参数指定要绑定的本地IP地址;InetAddress 用于可能具有多个IP地址的服务器,允许服务器指定哪个IP地址接受客户端请求
- ServerSocket():创建未绑定的服务器套接字。使用此构造函数时,在准备绑定服务器套接字时使用bind()方法
java.net.ServerSocket 的常用方法:
- int getLocalPort():返回服务器套接字正在侦听的端口;如果在构造函数中传入 0 作为端口号并让服务器自己打开端口,则此方法很有用
- Socket accept():等待传入的客户端,当客户端连接之后,ServerSocket 在未指定的端口上创建一个新的Socket,并返回对此新Socket的引用
- 如果使用 setSoTimeout() 方法设置了超时值,此方法将阻塞,直到客户端连接到指定端口上的服务器或套接字超时
- 如果没有指定超时值,则此方法无限期地阻塞
- void setSoTimeout(int timeout):设置服务器套接字在accept()期间等待客户端的时间的超时值
- void bind(SocketAddress host, int backlog):将套接字绑定到SocketAddress对象中的指定服务器和端口。如果已使用无参数构造函数实例化ServerSocket,请使用此方法
java.net.Socket:用于客户端与服务端相互通信
- 客户端通过实例化创建一个Socket对象
- 服务端通过 accept 方法接受客户端连接的返回值获取 Socket 对象
java.net.Socket 的构造函数:
- Socket(String host, int port):此方法尝试连接到指定端口上的指定服务器。如果此构造函数未引发异常,则连接成功并且客户端连接到服务器
- Socket(InetAddress host, int port):此方法与前一个构造函数相同,只是主机由InetAddress对象表示
- Socket(String host, int port, InetAddress localAddress, int localPort):连接到指定的主机和端口,在指定地址和端口的本地主机上创建套接字
- Socket(InetAddress host, int port, InetAddress localAddress, int localPort):同上面的方法
- Socket():创建一个未连接的套接字。使用connect()方法将此套接字连接到服务器
java.net.Socket 的常用方法:
1、连接和关闭:
- void connect(SocketAddress host, int timeout):将套接字连接到指定的主机。仅当使用无参数构造函数实例化Socket时才需要此方法
- void close():关闭套接字,此Socket对象不再能够再次连接到任何服务器
2、获取本机的地址和端口
- int getLocalPort():返回套接字在本地计算机上绑定的端口
- SocketAddress getLocalSocketAddress():返回socket在本地绑定的地址
- InetAddress getLocalAddress():返回socket在本地绑定的地址和端口
3、获取远程的地址和端口
- int getPort():返回套接字在远程计算机上绑定的端口
- SocketAddress getRemoteSocketAddress():返回远程套接字的地址
- InetAddress getInetAddress():返回此套接字连接到的另一台计算机的地址
4、获取输入输出流
- InputStream getInputStream():返回套接字的输入流,输入流连接到远程套接字的输出流
- OutputStream getOutputStream():返回套接字的输出流。输出流连接到远程套接字的输入流
InetAddress 类表示Internet协议(IP)地址:
- static InetAddress getByAddress(byte[] addr):给定原始IP地址返回InetAddress
- static InetAddress getByAddress(String host, byte[] addr):根据提供的主机名和IP地址创建InetAddress
- static InetAddress getByName(String host):根据主机名称确定主机的IP地址
- String getHostAddress():返回文本表示中的IP地址字符串
- String getHostName():获取此IP地址的主机名
- static InetAddress InetAddress getLocalHost():返回本地主机
- String toString():将此IP地址转换为String
示例,回声服务器:
// Server服务端
public class Server {
private static final int PORT = 8888;
private static final ExecutorService SERVICE = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
try {
// 1.创建ServerSocket实例
ServerSocket server = new ServerSocket();
// 2.设置等待超时时间
server.setSoTimeout(300000);
// 3.绑定端口
server.bind(new InetSocketAddress(Inet4Address.getLocalHost(), PORT));
while (true) {
// 4.接受客户端连接
Socket client = server.accept();
// 5.处理客户端消息
SERVICE.execute(() -> {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintStream printStream = new PrintStream(client.getOutputStream());) {
String msg = null;
while ((msg = bufferedReader.readLine()) != null) {
System.out.println("From client " + client.getRemoteSocketAddress() + ":" + msg);
printStream.println(msg);
if ("exit".equalsIgnoreCase(msg)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
public class Client {
private static final int PORT = 8888;
public static void main(String[] args) {
// 1.客户端创建Socket实例
final Socket client = new Socket();
try {
// 2.设置连接超时时间
client.setSoTimeout(3000);
// 3.连接服务端
client.connect(new InetSocketAddress(Inet4Address.getLocalHost(), PORT));
System.out.println("连接到服务端:" + client.getInetAddress());
/* 从控制台获取数据发送数据到服务端 */
// 获取控制台输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
// 4.从socket获取输出流
PrintStream printStream = new PrintStream(client.getOutputStream());
// 从socket获取输入流
BufferedReader socketReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String msg = null;
while ((msg = bufferedReader.readLine()) != null) {
// 5.往服务端发送消息
printStream.println(msg);
// 6.接受从服务端返回的消息
msg = socketReader.readLine();
System.out.println("From " + client.getRemoteSocketAddress() + ":" + msg);
if ("exit".equalsIgnoreCase(msg)){
break;
}
}
bufferedReader.close();
socketReader.close();
printStream.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}