客户端之间通讯: 实际上两个客户端不能直接通讯,要借助服务器来作为中转站,才能实现双方通讯。服务器
一个客户端发送数据到服务器,服务器将数据发送给(全部链接上服务器的)客户端,这样客户端之间实现了通讯。socket
服务器的代码:tcp
public class PcService {
private static final int SERVICEPORT=10086;
private static ArrayList<Socket> mClientList=new ArrayList<Socket>(); //记录链接上服务器的客户端
private ExecutorService mExecutorService; //建立线程池来管理
private ServerSocket serverSocket;
public static void main(String[] args) {
new PcService();
}
public PcService() {
try {
serverSocket=new ServerSocket(SERVICEPORT);
mExecutorService=Executors.newCachedThreadPool();
Socket clientSocket=null;
while(true){ //一接受到客户端发送来的数据,马上将信息转发给全部链接在线的客户端
clientSocket=serverSocket.accept();
mClientList.add(clientSocket);
mExecutorService.execute(new ThreadServer(clientSocket));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
this
static class ThreadServer implements Runnable{
PrintWriter printWriter;
BufferedReader bufferedReader;
String message;
Socket socket;线程
public ThreadServer(Socket socket) throws IOException {
this.socket=socket;
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
message=this.socket.getInetAddress()+"";
sendMessageToClient();
}
public void run() {
try {
while((message=bufferedReader.readLine())!=null){
if(message.trim().equals("exit")){//当一个客户端退出时
mClientList.remove(socket);
bufferedReader.close();server
printWriter.close();
socket.close();
sendMessageToClient();
break ;
}
else{
message=socket.getInetAddress()+"";
sendMessageToClient();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
//发送消息给每个链接的客户端
private void sendMessageToClient(){
try {
for(Socket client:mClientList){
printWriter=new PrintWriter(client.getOutputStream());
printWriter.println( message );
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}rem
监控TCP的状态: 心跳包get
作法:一个单独线程(心跳线程),来维护tcp的链接。
每隔一个时间就向服务器/客户端发送一段链接信息,当对方接受到后立刻回复对方。而后设置一个超时时间it
,过个时间就反复发几回。若是没有收到回复,则断定tcp断开了。io
用心跳包来维护链接,在发送心跳包异常时,能够认为对方短线,
或者指定时间超时后,未收到对方的心跳响应,也认为是对方短线。 或者就是Send的时候会直接报异常,能够直接认为是掉线了。