最近在做一个TCP SERVER的项目。好久没碰过SOCKET编程这块了,SO,刚刚做完这个项目,这里稍稍记录下一些简单的理解:
####服务器端:完成之后的服务端挺复杂的,因为需要响应客户端发送过来的各种请求,这里就不贴详细代码了,简单贴下其中要点
1、创建服务:
ServerSocket ss = new ServerSocket(port);
2、阻塞等待客户端连接:
while (_isServerStart) {
Socket client = ss.accept(); //阻塞等待
client.setSoTimeout(aliveTime);//设置心跳超时时间,超过这个时间将自动断开客户端连接
}
3、向客户端发送消息:
PrintWriter writer = new PrintWriter(client.getOutputStream(), true); //得到客户端输出流
writer.println(msg); //输出消息到客户端
4、接收客户端消息:
while (_threadIsRunning) {
if(client!=null){
//得到客户端输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
msg = reader.readLine(); //阻塞等待客户端输入
if(msg==null){ //说明该客户端已经离线,则从客户端列表中移除该客户端
println("有设备已经关闭,ID="+getClientIdByClient(client));
closeClient(client);
}else{
println(msg);//打印客户端信息
}
}
}
###客户端
/**
* 监听服务器消息的线程
* @author Nemo
*
*/
public class ClientThread extends Thread {
private Socket client; //服务器端
private BufferedReader reader; //服务器端输入流
private PrintWriter writer; //服务器端输出流
private Thread keepAliveThread = null;//心跳线程
String _server_ip = "127.0.0.1"; //服务器IP
int _server_port = 1228; //服务器开放端口
boolean threadIsRunning = true;//是否保持主线程运行的标志
boolean isKeepAlive = true;//是否要保持心跳
public ClientThread() {
try {
client = new Socket(_server_ip, _server_port);//这里设置连接服务器端的IP的端口
println("连接服务器成功:端口"+_server_port+",正在登录中..."); //打印到客户端前台展示
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
writer = new PrintWriter(client.getOutputStream(), true);// 如果为 true,则 println、printf 或 format 方法将刷新输出缓冲区
//开启心跳包维持通信
sendAlivePackage();
} catch (Exception e) {
e.printStackTrace();
println("连接服务器失败>>"+_server_ip+":"+_server_port);
println(e.toString());
}
this.start();//开启线程
}
public void run() {
String msg = "";
//阻塞等待服务器端发送消息
while (threadIsRunning) {
try {
msg = reader.readLine();
if(msg==null){
println("服务器断开连接!");
threadIsRunning = false;
client.close();
}
} catch (Exception e) {
e.printStackTrace();
println("服务器断开连接!");
break;
}
if (msg != null && msg.trim() != "") {
println(">>" + msg);
}
}
}
/**
* 发送消息到服务器
* @param msg
*/
public void sendMsg(String msg) {
try {
writer.println(msg);
} catch (Exception e) {
println(e.toString()+"sendMsg");
}
}
/**
* 发送心跳包
*/
private void sendAlivePackage(){
keepAliveThread = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
writer.println("{'method':'keepAlive'}"); //发送心跳信息,服务器端需要对这个信息进行过滤处理
Thread.sleep(5000); //每5s发送一次心跳,维持跟服务器端的连接
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
keepAliveThread.start();
}
/**
* 打印消息到客户端前台
* @param s
*/
public void println(String s) {
if (s != null) {
//this.ui.taShow.setText(this.ui.taShow.getText() + s + "\n"); //这里是打印到客户端前台的方法,这里就不贴出来了
System.out.println(s + "\n");
}
}
}