Java网络编程
Socket技术
通过Socket技术(它是计算机之间进行通信的一种约定或一种方式),我们就可以实现两台计算机之间的通信
Socket也被翻译为套接字
,是操作系统底层提供的一项通信技术,它支持TCP和UDP
而Java就对socket底层支持进行了一套完整的封装,我们可以通过Java来实现Socket通信
代码语言:javascript复制//服务端
public static void main(String[] args) {
try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
System.out.println("正在等待客户端连接...");
while (true){ //无限循环等待客户端连接
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:" socket.getInetAddress().getHostAddress());
}
}catch (IOException e){
e.printStackTrace();
}
}
代码语言:javascript复制//客户端
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8080)){
System.out.println("已连接到服务端!");
}catch (IOException e){
System.out.println("服务端连接失败!");
e.printStackTrace();
}
}
一旦TCP连接建立,服务端和客户端之间就可以相互发送数据,直到客户端主动关闭连接。
Socket进行数据传输
短链接一收一发:
代码语言:javascript复制public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8080);
Scanner scanner = new Scanner(System.in)){
System.out.println("已连接到服务端!");
OutputStream stream = socket.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stream); //通过转换流来帮助我们快速写入内容
System.out.println("请输入要发送给服务端的内容:");
String text = scanner.nextLine();
writer.write(text 'n'); //因为对方是readLine()这里加个换行符
writer.flush();
System.out.println("数据已发送:" text);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("收到服务器返回:" reader.readLine());
socket.close(); //关闭链接
}catch (IOException e){
System.out.println("服务端连接失败!");
e.printStackTrace();
}finally {
System.out.println("客户端断开连接!");
}
}
代码语言:javascript复制public static void main(String[] args) {
try(ServerSocket server = new ServerSocket(8080)){ //将服务端创建在端口8080上
System.out.println("正在等待客户端连接...");
Socket socket = server.accept();
System.out.println("客户端已连接,IP地址为:" socket.getInetAddress().getHostAddress());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //通过
System.out.print("接收到客户端数据:");
System.out.println(reader.readLine());
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
writer.write("已收到!");
writer.flush();
socket.close(); //关闭链接
}catch (IOException e){
e.printStackTrace();
}
}
Socket相关使用
手动关闭单向的流:
代码语言:javascript复制socket.shutdownOutput(); //关闭输出方向的流
socket.shutdownInput(); //关闭输入方向的流
设定IO超时时间:
代码语言:javascript复制socket.setSoTimeout(3000);
当超过设定时间都依然没有收到客户端或是服务端的数据时,会抛出异常
链接构造分离方式:
代码语言:javascript复制try (Socket socket = new Socket(); //调用无参构造不会自动连接
Scanner scanner = new Scanner(System.in)){
socket.connect(new InetSocketAddress("localhost", 8080), 1000); //手动调用connect方法进行连接
心跳链接检测:
代码语言:javascript复制socket.setKeepAlive(true);
如果设置了keeplive为 true,当对方没有发送任何数据过来,超过一个时间(看系统内核参数配置),那么我们这边会发送一个ack探测包发到对方,探测双方的TCP/IP连接是否有效。
TCP在传输过程中,实际上会有一个缓冲区用于数据的发送和接收,手动调整其大小来优化传输效率:
代码语言:javascript复制socket.setReceiveBufferSize(25565); //TCP接收缓冲区
socket.setSendBufferSize(25565); //TCP发送缓冲区