使用Java进行Socket编程
简介
本文主要使用
Java.net
包下的Socket与ServerSocket实现一个简单的单服务端与多客户端之间的通信,该通信模型为BIO模型,且不进行SSL/TLS通信加密。- 使用SSL/TLS通信加密的可查看:基于SSL/TLS的Java Socket编程
- 在本项目中,服务端采用线程池维护一定数量的线程,用以保持与客户端间的通信。
主要代码
服务端
服务端主线程 Server.java
- 该部分维护一个线程池,线程池的参数由
CORE_POOL_SIZE
,MAXIMUM_POOL_SIZE
,KEEP_ALIVE_TIME
给出,并新建一个ServerSocket,在main线程中监听ServerSocket,获取新的Socket连接,并创建业务线程。
serverSocket = new ServerSocket(PORT);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>());
while (true){
Socket socket = serverSocket.accept();
System.out.println("Server accept a socket.");
threadPoolExecutor.execute(new ServerTask(socket));
}
服务端业务线程 ServerTask.java
- 该线程获取socket的输入输出流,为了方便演示,下列仅实现输入流的读取。对于InputStream与OutputStream的多线程读取不做实现。
- 下列线程中,读取InputStream中的内容,并在控制台输出客户端的相关信息。
private static final int BUFFER_SIZE = 1024;
private Socket serverSocket;
public ServerTask(Socket socket){
this.serverSocket = socket;
}
public void run() {
try {
InputStream in = serverSocket.getInputStream();
OutputStream out = serverSocket.getOutputStream();
byte[] data=null;
while (serverSocket.isConnected()){
data = new byte[BUFFER_SIZE];
String resultData = new String(data);
if (in.read(data,0,BUFFER_SIZE) > -1){
System.out.println("Server Receives Message from port: "
+ serverSocket.getInetAddress().getHostAddress() + ":"
+ serverSocket.getPort());
System.out.println(new String(data, Charset.forName("UTF-8")));
System.out.println("Receive Time:" + System.currentTimeMillis());
}
}
}catch (IOException ex){
ex.printStackTrace();
}finally {
try {
serverSocket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
客户端
客户端线程 ClientTask.java
- 该线程主要用于新建与目标服务端的Socket连接,并间隔2s向OutputStream进行写入
private static final String HOST = "127.0.0.1";
private static final int PORT = 8080;
private Socket socket;
private String clientName;
public ClientTask(String name){
this.clientName = name;
socket = new Socket();
try {
socket.connect(new InetSocketAddress(HOST,PORT),60);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
OutputStream out = socket.getOutputStream();
while (true){
String transferData = "Client " + clientName + " heart beat.";
System.out.println(transferData);
out.write(transferData.getBytes(Charset.forName("UTF-8")));
System.out.println("Transfer Time: " + System.currentTimeMillis());
Thread.sleep(2000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建客户端
- 该步可通过新建客户端线程
ClientTask.java
并运行,该部分实现方法有多种,下面提供一个简单实现
public static void main(String[] args){
new Thread(new ClientTask("Client_01")).run();
}
运行结果示例
- 服务端运行结果
- 客户端运行结果
评论已关闭