JAVA中的通信主要靠java.net和java.nio包中的类实现,下面我将演示如何利用java.net包中的类来模拟一个用于收发报文的长连接服务器。
服务器的功能:
1. 接收来自客户端的请求报文
2. 检测报文是否符合规范
3. 返回应答报文给客户端
实例代码如下:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @description
* @version 2015年1月26日 下午2:10:39
*/
public class CoreSimulate implements Runnable {
private final int port;
private final String responseFileName;
public CoreSimulate(int port, String responseFileName) {
this.port = port;
this.responseFileName = responseFileName;
}
public static void main(String[] args) {
if(args.length < 2) {
System.out.println("请输入参数:1:监听端口 2:返回报文文件名");
}else {
new Thread(new CoreSimulate(Integer.parseInt(args[0]), args[1])).start();
}
}
public void run() {
try {
System.out.printf("核心模拟器启动成功,监听端口:{%s},返回报文名称:{%s}", port, responseFileName);
ServerSocket server = new ServerSocket(port);
while (true) {
new Thread(new RunServer(server.accept())).start();
}
} catch (Throwable t) {
t.printStackTrace();
}
}
class RunServer implements Runnable {
private final Socket conn;
RunServer(Socket conn) {
this.conn = conn;
}
public void run() {
InputStream in = null;
try {
in = conn.getInputStream();// 创建一个从socket中读文本行的流
final OutputStream out = conn.getOutputStream();
byte[] request;
byte[] response;
while (true) {
// 判断可读长度是否达到数据长度
if (in.available() > 0) {
request = new byte[in.available()];
in.read(request);
System.out.println("核心收到求情报文...\n"+ request);
response = createResponseMsg(responseFileName);
System.out.println("核心响应报文:\n" + response);
System.out.println("核心响应报文,响应报文来自:" + responseFileName);
out.write(response);
out.flush();
out.close();
} else {
System.out.println("发送到核心请求报文长度为零!!!");
out.write("发送到核心请求报文长度为零!!!".getBytes());
out.flush();
out.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(in != null)
in.close();
if (conn != null)
conn.close();
} catch (IOException ioe) {
}
}
}
}
// 创建返回报文
private byte[] createResponseMsg(String fileName) {
byte[] tempBytes = null;
try {
InputStream in = this.getClass().getResourceAsStream(fileName);
int total = in.available();
tempBytes = new byte[total];
in.read(tempBytes);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return tempBytes;
}
}
此类可以直接运行,传入两个参数,第一个参数是服务器监听的端口,第二个参数是服务器返回报文文件名(该文件需与编译后的classes文件在同一目录)。
从代码里可以看出,服务端每收到一个请求就会建立一个Socket连接,当返回请求后,连接便会中断。但服务器端仍会继续监听端口用于接收请求。
这里,没有写客户端的代码,给大家提供一个客户端模拟器软件,用于向指定的ip下的端口发送报文。下载页面有使用方法。
使用上面的客户端模拟软件就可以给模拟的服务器发送请求报文了。
当然,你也可以尝试写一个客户端。
这样,就简单的模拟了一个长连接的服务器。
本文介绍了如何使用JAVA的java.net包创建一个长连接服务器,该服务器能接收客户端请求报文,检查报文规范,并返回应答。通过提供客户端模拟器软件,读者可以实践向服务器发送报文。

411

被折叠的 条评论
为什么被折叠?



