调用方式:
public class DemoApplication {
public static void main(String[] args) {
SocketServer socketServer = new SocketServer();
socketServer.start();
// SpringApplication.run(DemoApplication.class, args);
}
}
介绍:
(1)SocketServer的run方法用来接收socket连接,调用socketHandle.run
(2)SocketHandle的run方法用来处理socket的输入输出流,调用SocketHandle.handle
(3)SocketHandle的handle静态方法用来处理用户输入的字符串,可以调用自定义的处理方法
另:
SocketHandle的run方法在128行给了3种输入流处理方式,越后面越好,但要客户端配合。
SocketServer.java:
// 文件名 SocketServer.java
package com.example.demo;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SocketServer extends Thread {
int port = 34560;
int nThreads = 100;
public void service() {
this.run();
}
@Override
public void run(){
ExecutorService threadPool = null;
ServerSocket server = null;
try{
// 监听指定的端口
server = new ServerSocket(port);
// server将一直等待连接的到来
System.out.println("server将一直等待连接的到来");
System.out.println("");
//如果使用多线程,那就需要线程池,防止并发过高时创建过多线程耗尽资源
threadPool = Executors.newFixedThreadPool(nThreads);
while (true) {
Socket socket = null;
try{
socket = server.accept();
}catch(Exception e){
e.printStackTrace();
if(socket!=null){socket.close();}
}
System.out.println("获得连接");
SocketHandle socketHandle = new SocketHandle(socket);
threadPool.submit(socketHandle);
}
} catch(Exception e){
System.out.println("获取socket,异常错误:");
System.out.println(e.toString());
e.printStackTrace();
System.out.println("");
} finally {
if(server!=null){
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(threadPool!=null){
threadPool.shutdown();
}
}
}
}
class SocketHandle implements Runnable {
// String charsetName = "UTF-8";
String charsetName = "GBK";
int socketSoTimeout = 5 * 60 * 1000; // 毫秒单位
Socket socket;
SocketHandle(Socket socket){
this.socket = socket;
}
public int 序号值 = 0;
public String 获得序号(){
if (序号值 > 50000){
序号值 = 0;
}
++序号值;
return Integer.toString(序号值) + ": ";
}
@Override
public void run(){
// 建立好连接后,从socket中获取输入输出流,并建立缓冲区进行读取写入
InputStream inputStream = null;
OutputStream outputStream = null;
BufferedReader reader = null;
BufferedWriter writer = null;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
reader=new BufferedReader(new InputStreamReader(inputStream,charsetName));
writer=new BufferedWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream),charsetName));
// 设定最长 接收数据间隔时间
socket.setSoTimeout(socketSoTimeout);
byte[] bytes = new byte[102400];
int len;
String line;
while(true){
// 这个socket状态判断,是本地状态判断,无法得知远端状态
if(socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected()&& !socket.isInputShutdown() && !socket.isOutputShutdown()) {
}else{
System.out.println("socket不可用,准备断开连接");
break;
}
// try{
// socket.sendUrgentData(0);
// }catch (Exception e){
// System.out.println("发送紧急包失败,准备断开连接");
// break;
// }
// -- 数据读取方式
// (1)直接读取方式
len = inputStream.read(bytes);
if(len == -1){
break;
}
line = new String(bytes, 0, len, charsetName);
System.out.println(获得序号() + "收到了信息:" + line);
String rst_str = SocketHandle.handle(line);
System.out.println("返回:" + rst_str);
if(rst_str!=null && !(rst_str.trim().replaceAll("\\s*|\t|\r|\n", "").isEmpty())) {
rst_str += "\r\n";
writer.write(rst_str);
writer.flush();
}
// (2)换行结尾方式
// line = reader.readLine();
// if(line != null){
// System.out.println(获得序号() + "收到了信息:" + line);
// String rst_str = SocketHandle.handle(line);
// System.out.println("返回:" + rst_str);
// if(rst_str!=null && !(rst_str.trim().replaceAll("\\s*|\t|\r|\n", "").isEmpty())) {
// rst_str += "\r\n";
// writer.write(rst_str);
// writer.flush();
// }
// }else{
// break;
// }
// (3)约定长度方式
// 首先读取两个字节表示的长度
// int first = inputStream.read();
// //如果读取的值为-1 说明到了流的末尾,Socket已经被关闭了,此时将不能再去读取
// if(first==-1){
// break;
// }
// int second = inputStream.read();
// int length = (first << 8) + second;
//
// StringBuilder sb = new StringBuilder();
// int readLength=0;
// while(readLength<length){
// int read = inputStream.read(bytes, readLength, length-readLength);
// readLength+=read;
// // 注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
// sb.append(new String(bytes, 0, read, charsetName));
// }
// line = sb.toString();
// System.out.println(获得序号() + "收到了信息:" + line);
// String rst_str = SocketHandle.handle(line);
// System.out.println("返回:" + rst_str);
// if(rst_str!=null && !(rst_str.trim().replaceAll("\\s*|\t|\r|\n", "").isEmpty())) {
// String message = rst_str;
// // 首先需要计算得知消息的长度
// byte[] sendBytes = message.getBytes(charsetName);
// // 然后将消息的长度优先发送出去
// outputStream.write(sendBytes.length >>8);
// outputStream.write(sendBytes.length);
// // 再将剩下的消息发送出去
// outputStream.write(sendBytes);
// outputStream.flush();
// }
}
} catch (Exception e) {
// 意料中有两种错误,读超时 和 连接重置
System.out.println("处理socket,异常错误:");
// e.printStackTrace();
System.out.println(e.toString());
} finally {
System.out.println("关闭连接");
System.out.println("");
try {
if(reader!=null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(writer!=null)
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(inputStream!=null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(outputStream!=null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String handle(String input_str){
String rst_str = null;
try{
rst_str = "hello world";
} catch(Exception e){
System.out.println("处理用户输入,异常错误:");
System.out.println(e.toString());
System.out.println("");
rst_str = null;
} finally {
}
return rst_str;
}
}
用来测试的client端:
SocketClient.java
// 文件名 SocketClient.java
package com.example.demo;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) throws Exception{
// 要连接的服务端IP地址和端口
String host = "127.0.0.1";
int port = 34560;
String charsetName = "GBK";
// 与服务端建立连接
Socket socket = new Socket(host, port);
// 建立连接后获得输出流
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream,charsetName));
while(true){
System.out.println("请输入数据:");
String message = br.readLine();
// message += "\r\n";
outputStream.write(message.getBytes(charsetName));
outputStream.flush();
String sb = reader.readLine();
System.out.println("get message from server: " + sb);
System.out.println("");
}
// br.close();
// reader.close();
// inputStream.close();
// outputStream.close();
// socket.close();
}
}
效果:
源文件: