前言
因项目要求,需要定时推送数据给硬件后台,然后根据后台不定时请求,做出响应。写了一个socket传输数据,传输的时候可以正常传输,但是到接收后台请求,处理请求的时候会一直监听,影响传输的效率,所以在基础上做了一些简单的修改,把传输和接收分开,同时进行。
正文
文中有socket服务端使用和简单的客户端测试代码,可以根据不同的项目需求做出修改。文中使用了两个线程来让传输和接收互不干扰,并且接收的时候没有用BufferedReader的readLine()方法,readLine()方法接收方便,但是客户端不确定何时发送请求,导致会一直监听,影响性能,而且比较确定客户端会发送的数据长度,所以最后选择了InputStream直接读取byte数组。
新建socket服务端传输数据
public class StatusSocket extends Thread{
private static Logger log = LoggerFactory.getLogger(StatusSocket.class);
private static int PORT = Integer.valueOf(ConfigVariable.STATUS_PORT);
@Override
public void run() {
try {
ServerSocket serverSocket = buildServerSocket();
serverSocket.setSoTimeout(20000);
Thread.sleep(2000);
log.info("开启天线实时推送服务:");
while (!Thread.currentThread().isInterrupted() ) {
Socket socket = null;
try {
socket = serverSocket.accept();
socket.setKeepAlive(true);
} catch (SocketTimeoutException e) {
serverSocket.close();
serverSocket = buildServerSocket();
continue;
}
new ReceiveSocket(socket).start();
new SendSocket(socket).start();
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
/** 数据推送线程 */
class SendSocket extends Thread {
private Socket socket;
SendSocket(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedWriter writer = null;
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(socket.getOutputStream());
writer = new BufferedWriter(osw);
while(socket.getKeepAlive()) {
//这里放入需要传输的数据 str
String str="";
//BufferedReader的readLine方法是按行读取,末尾加上\n方便对方读取
writer.write(str+"\n");
writer.flush();
Thread.sleep(1500);
}
} catch (Exception e) {
continue;
}finally {
try {
writer.close();
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/** 请求回复线程 */
class ReceiveSocket extends Thread {
private Socket socket;
ReceiveSocket(Socket socket){
this.socket = socket;
}
@Override
public void run() {
//BufferedReader reader = null;
//InputStreamReader isr = null;
InputStream in = null;
try {
in = socket.getInputStream();
} catch (IOException e1) {
e1.printStackTrace();
};
BufferedWriter writer = null;
OutputStreamWriter osw = null;
try {
//isr = new InputStreamReader(socket.getInputStream());
//reader = new BufferedReader(isr);
osw = new OutputStreamWriter(socket.getOutputStream());
writer = new BufferedWriter(osw);
//while(null != (readStr = reader.readLine())){
byte[] buffer = new byte[1024];
while(in.read(buffer) > 0){
String readStr = new String(buffer);
JSONObject readJson = JSONObject.parseObject(readStr.trim());
if("updateMsg".equals(readJson.getString("msgType"))) {
//做出处理
//。。。。
//处理成功后回复
String result ="ok";
writer.write(result.toString()+"\n");
writer.flush();
}
}
} catch (Exception e) {
continue;
}finally {
try {
writer.close();
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/* 初始化socket */
private ServerSocket buildServerSocket() throws IOException, SocketException {
ServerSocket serverSocket = new ServerSocket(PORT); // 端口号
serverSocket.setSoTimeout(20000);
return serverSocket;
}
}
socket客户端测试
客户端测试时先推送数据,然后开启循环读取服务端推送的数据,实际应用时,可以写成不同的线程或者按实际需求修改顺序。
public class SocketDemo {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",8989);
socket.setSoTimeout(5 * 1000);
OutputStream out = socket.getOutputStream();
socket.setKeepAlive(true);
InputStreamReader input = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(input);
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter writer = new BufferedWriter(osw);
String lineString = null;
writer.write("{\"msgType\":\"updateMsg\",\"txpower\":9}");
writer.flush();
while (null != (lineString = reader.readLine())) {
System.out.println("-----lineString:-----\r\n"+lineString);
}
osw.close();
writer.close();
input.close();
reader.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}