好记性不如烂笔头,做过的东西简单记录一下!
用起来很简单,用好不容易!
网上一搜一大堆demo,随便拿一个简单的来深入!
首先,起服务,指定端口
//服务端
public class SocketServer {
public static void main(String[] args) throws IOException {
try{
ServerSocket server = new ServerSocket(7777);
System.out.println("开始对端口7777进行监听");
while(true){
Socket sc=server.accept();
DataInputStream din=new DataInputStream(sc.getInputStream());
DataOutputStream dout=new DataOutputStream(sc.getOutputStream());
System.out.println("客户端ip地址是:"+sc.getInetAddress());
System.out.println("客户端端口号是:"+sc.getPort());
System.out.println("本地端口号是:"+sc.getLocalPort());
System.out.println("客户端消息是:"+din.readUTF());
dout.writeUTF("已收到你发来的消息!!");
/**
* PS:用完一次就关闭,再用再开,用完再关,这就是短链接!
* 用完不关,一直挂着,再用,还连这里,这就是长链接!
* 如下,注释掉下面的几个.close();就是长连接!
* @Author qinzy
*/
din.close();//可以注释掉
dout.close();//可以注释掉
sc.close();//可以注释掉
server.close();//可以注释掉
}
}catch(Exception e){
e.printStackTrace();
}
}
}
其次,起客户端,链接服务
不指定本地端口(客户端端口)
public class SocketClient {
public static void main(String[] args) throws IOException {
/**
* PS:这里每执行一次,会分配一个新的本地端口去链接服务(在原来的本地端口没有死的情况下)
* 可以搞个死循环,看你电脑啥时候端口会分配完,端口不够用了会怎样,报啥错!
* @Author qinzy
*/
Socket msgSocket = new Socket(ip,7777);
DataInputStream din=new DataInputStream(msgSocket.getInputStream());
DataOutputStream dout=new DataOutputStream(msgSocket.getOutputStream());
dout.writeUTF("你好");
dout.flush();
System.out.println(din.readUTF());
}
}
指定本地端口(客户端端口)
public class SocketClient {
public static void main(String[] args) throws IOException {
/**
* PS:这里执行一次没问题,第二次会提示JVM_Bind(就是端口占用)
* 如果就只想用这个端口怎么办,那就用完关闭,但是关闭再立即重启,还是占用
* 底层方法需要等2分钟,2分钟后才能真正关闭,然后再连,就可以了
* @Author qinzy
*/
Socket msgSocket = new Socket(ip,7777,realIp,9999);
DataInputStream din=new DataInputStream(msgSocket.getInputStream());
DataOutputStream dout=new DataOutputStream(msgSocket.getOutputStream());
dout.writeUTF("你好");
dout.flush();
System.out.println(din.readUTF());
}
}
单个长连接+指定端口
上面只是简单示例,真正应用起来会有很多情况。
要结合实际业务:
比如
1:异常不能直接抛,要catch,如果直接抛,有没有统一异常处理,怎么区别异常,等等
2:长连接如果出现异常,要不要关闭socket,如果有很多异常,每次都关,每次都等2分钟,业务允许吗?还有,如果一直关,再一直连,那还算长连接吗?不如直接用短链接合适!
3:读写异常的时候,如果直接把流关掉,那么socket就也断了,再用原来的流去读写的话会异常。
直接关闭流后,可以输出一下socket的状态,会发现,socket是已关闭,但是连接没断,这时候再用指定端口去创建新连接,会长时间连不上,直到服务器发现这个客户端彻底失联了,才会认定为断开,这时候才能创建成功!
单个长连接+指定端口+小于2分钟重连等待
1、首先长连接不解释
2、读写异常的时候,不直接关闭流,而是把原来的流置空,再次从socket中去获取新的流
3、心跳机制,固定时间间隔去确认一次链接,确保链接正常
4、失败重试,心跳N次内重试,N+1次判定彻底失败,关闭链接
5、关闭的时候先关流,再关socket
多个长连接+指定端口+小于2分钟重连等待
方案1、开多个任务,每个任务维护自己的长连接,互不干扰
方案2、每个长连接给特定标识,找个地方统一保存每个长连接,根据不同标识区别维护
单个容器+多个长连接+指定端口+小于2分钟重连等待
公司业务原因,容器同其他业务,以及长连接耦合度太高,最终决定用以上方案2。
方案2:
存东西可以有很多地方,数据库、缓存、集合、map、等等,用什么不重要,合适才重要!
暂时就到这里,日后再有需求再继续深入!