Socket 编程
1 Socket
- Socket通信分为服务端、客户端
- 服务端:接收客户端发送的数据--request,然后进行数据处理,最后把处理结果返回给客户端--response
- 客户端:把数据发送给服务端,然后经过服务端处理,并接受服务端数据
- BIO:阻塞的IO
2 Socket 通信
2.1 需求
1 建立一个可以进行通信的Socket服务端、客户端
2 客户端和服务端可以持续通信
3 客户端输出exit则退出通信
2.2 Code
2.2.1 FinalCode Code
package com.xk.bigdata.java.utils;
public class FinalCode {
// Socket
public final static int PORT = 8888;
public final static String EXIT = "exit";
public final static String HOSTNAME = "localhost";
}
2.2.2 Server Code
package com.xk.bigdata.java.io.socket;
import com.xk.bigdata.java.utils.FinalCode;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端
*/
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// 创建socket server
serverSocket = new ServerSocket(FinalCode.PORT);
System.out.println("Socket Server 已经创建,端口是:" + FinalCode.PORT);
while (true) {
// 创建接受客户端发送数据的Socket
Socket socket = serverSocket.accept();
System.out.println("端口为:" + socket.getPort() + "的客户端已经创建连接");
// 创建IO流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String message = null;
while ((message = reader.readLine()) != null) {
if (null != message) {
System.out.println("客户端发送过来的数据:" + message);
writer.write("-----------------" + message + "\n");
writer.flush();
if (FinalCode.EXIT.equalsIgnoreCase(message)) {
System.out.println("客户端【" + socket.getPort() + "】 已经退出");
break;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != serverSocket) {
try {
serverSocket.close();
System.out.println("Socket Server 已经关闭");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.2.3 Client Code
package com.xk.bigdata.java.io.socket;
import com.xk.bigdata.java.utils.FinalCode;
import java.io.*;
import java.net.Socket;
/**
* 客户端
*/
public class Client {
public static void main(String[] args) {
Socket socket = null;
try {
// 创建与服务端的连接
socket = new Socket(FinalCode.HOSTNAME, FinalCode.PORT);
System.out.println("客户端HOSTNAME:" + FinalCode.HOSTNAME + " PORT:" + FinalCode.PORT + "已经创建连接");
// 创建IO相关的socket流
while (true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
// 从控制台读取数据
String requestMessage = console.readLine();
writer.write(requestMessage + "\n");
writer.flush();
System.out.println("发送给服务端数据:" + requestMessage);
String responseMessage = reader.readLine();
System.out.println("responseMessage :" + responseMessage);
// 客户端是否退出
if (FinalCode.EXIT.equalsIgnoreCase(requestMessage)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != socket) {
try {
socket.close();
System.out.println("客户端HOSTNAME:" + FinalCode.HOSTNAME + " PORT:" + FinalCode.PORT + "已经关闭连接");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.3 结果
2.3.1 Server Console
Socket Server 已经创建,端口是:8888
端口为:64336的客户端已经创建连接
客户端发送过来的数据:hadoop
客户端发送过来的数据:spark
客户端发送过来的数据:exit
客户端【64336】 已经退出
2.3.2 Client Console
客户端HOSTNAME:localhost PORT:8888已经创建连接
hadoop
发送给服务端数据:hadoop
responseMessage :-----------------hadoop
spark
发送给服务端数据:spark
responseMessage :-----------------spark
exit
发送给服务端数据:exit
responseMessage :-----------------exit
客户端HOSTNAME:localhost PORT:8888已经关闭连接
- 这份代码Server同时只可以接收到一个client的消息,并通信
- serverSocket.accept()这个是阻塞的
The method blocks until a connection is made.