java socket 长连接事例
一 .我们知道java的socket是基于TCP的连接,而ServerSocket 的accept()方法是阻塞的,直到有客户端连接到服务器端,我们常用多线程的方式来实现服务器端响应多个客户端,以下是代码:
public class server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务器端--开始监听");
while(true){
Socket socket = serverSocket.accept();
ServerHandel hm = new ServerHandel(socket);
Thread t = new Thread(hm);
t.start();
}
//1.socket 的输入输出流任意一个关闭,则socket都不可再用了,所以要关闭就一起关闭了。
//2.socket 流的读是阻塞的,A不要输入流关闭前时,要考虑B端的输出流是否还需要写。否者,B端一直等待A端接收,而A端却接受不了,B一直阻塞,在长连接中尤其要注意,注意流的结束标志
//3.io 流最后一定要关闭,不然会一直占用内存,可能程序会崩溃。文件输出也可能没有任何信息
//4.字符输出推荐使用printWriter 流,它也可以直接对文件操作,它有一个参数,设置为true 可以自动刷新,强制从缓冲中写出数据
//5.缓冲流 都有 bufw.newLine();方法,添加换行
//6.输入流 是指从什么地方读取/输出流是指输出到什么地方
//7.OutputStreamWriter和InputStreamReader是转换流,把字节流转换成字符流
//8.Scanner 取得输入的依据是空格符,包括空格键,Tab键和Enter键,任意一个按下就会返回下一个输入,如果需要包括空格之类的则用bufferreader来获取输入
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
二 这里有2个概念介绍下:
1.短连接: 当输出流发送完毕后,立即关闭流,下次发送,需要新建通信. 会频繁的新建通信,丢弃通信,效率低
2.长连接: 客户端和服务器端都不关闭流, 可以多次发送数据
三 长连接的使用需要注意一些问题:
1.客户端和服务器端,不能关闭任一socket的输入流或者输出流,否则socket通信会关闭
2.由于都不关闭连接,而read方法又是阻塞的,会一直读取数据,不知道何时读取结束,所以要约定通信协议,如特定字符,或者使用包头+包体的方式,传递数据,包头固定长度,里面保存包体长度等信息,这样服务端就知道读取到何时结束了.(本文使用此种方式)以下是代码:
客户端:
public class client {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1",9999);
System.out.println("客户端开始连接");
//一直读取控制台
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true){
//包体
byte [] content = br.readLine().getBytes();
//包头,固定4个字节,包含包体长度信息
byte [] head = Tool.intToByteArray1(content.length);
BufferedOutputStream bis = new BufferedOutputStream(socket.getOutputStream());
bis.write(head);
bis.flush();
bis.write(content);
bis.flush();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
socket.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
服务器端线程类:
public class ServerHandel implements Runnable {
public static int count = 0;
Socket socket = null;
public ServerHandel(Socket socket){
count++;
this.socket = socket;
System.out.println("用户"+count+"接入");
}
@Override
public void run() {
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(socket.getInputStream());
while (true){
byte [] head = new byte[4];
bis.read(head);
byte [] data = new byte[Tool.byteArrayToInt(head)];
bis.read(data);
System.out.println(new String(data).trim());
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
bis.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四 由于以字节数组传递包头,就涉及到字节数组和int类型转换的问题,java中int类型是4个字节,所以用byte[4]来装,
//int 转字节数组
public static byte[] intToByteArray1(int i) {
byte[] result = new byte[4];
result[0] = (byte)((i >> 24) & 0xFF);
result[1] = (byte)((i >> 16) & 0xFF);
result[2] = (byte)((i >> 8) & 0xFF);
result[3] = (byte)(i & 0xFF);
return result;
}
public static byte[] intToByteArray2(int i) throws Exception {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(buf);
out.writeInt(i);
byte[] b = buf.toByteArray();
out.close();
buf.close();
return b;
}
//字节数组转int
public static int byteArrayToInt(byte[] b) {
int intValue=0;
for(int i=0;i<b.length;i++){
intValue +=(b[i] & 0xFF)<<(8*(3-i));
}
return intValue;
}
五 对于网络IO有一些基本的处理规则如下:
1.减少交互的次数。比如增加缓存,合并请求。
2.减少传输数据大小。比如压缩后传输、约定合理的数据协议。
3.减少编码。比如提前将字符转化为字节再传输。
4.根据应用场景选择合适的交互方式,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞。
六 在jdk1.4种引入了 java.nio.* 包, 大大提高了io的性能,并加入了非阻塞io模型,引入了通道和基础数据类型的buffer类型,各位看官可以去看看,这里就不说了,有空再总结.
java socket 长连接事例相关推荐
- java Socket长连接
java socekt 同步套节字编程主要用到java.net.Socket类,通常情况下我们需要socket的长连接模式.其次就是在连接的另一端断开之后需要及时响应. 对于连接的判断,socket提 ...
- java socket长连接怎么维持_socket长连接的维持
import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date;/** * 维持连接的消息对 ...
- java Socket 长连接 心跳包 客户端 信息收发 demo
今天写了个socket的测试小程序,代码如下 import java.io.IOException; import java.io.InputStream; import java.io.Output ...
- Java实现SSL Socket长连接
一.单向认证 1.生成服务端密钥(配置了jdk的环境变量即可用keytool命令) 命令:keytool -genkey -keystore server_ks.jks -storepass serv ...
- android端 socket长连接 架构
看过包建强的<App研发录>之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及socket相 ...
- java前端长连接框架_Java如何实现长连接
实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端: Client通过持有Socket的对象,可以随时(使 ...
- 【Socket】关于socket长连接的心跳包
TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive) 据网络搜索到的资料解释如下 内网机器如果不主动向外发 ...
- socket 长链接linux,手把手教你写 Socket 长连接
原标题:手把手教你写 Socket 长连接 8点43分打卡 就是真爱 本文转载自公众号 玉刚说,由玉刚说写作平台[1]提供写作赞助 原作者:水晶虾饺[2] 版权声明:本文版权归微信公众号玉刚说所有,未 ...
- 手把手教你写 Socket 长连接
本文由玉刚说写作平台[1]提供写作赞助 原作者:水晶虾饺[2] 版权声明:本文版权归微信公众号 玉刚说 所有,未经许可,不得以任何形式转载 本篇我们先简单了解一下 TCP/IP,然后通过实现一个 ec ...
最新文章
- 基于相机和低分辨率激光雷达的三维车辆检测
- 并发编程中一种经典的分而治之的思想!!
- 2012体感发展加速,微软再添新对手
- 【常见问题】Can not perform this action after onSaveInstanceState
- Golang 匿名结构体及测试代码编写技巧
- Mongodb数据库(1.mongodb的介绍(非关系型数据库)下载与安装(Windows10))
- 探索停车黑科技,知位停车破局停车难题!
- 通过QQ或者QQ帮助别人学习Lync之一
- centos7卸载mysql数据库,CentOS7 安装卸载MySQL
- python十大装b语法_Python 十大语法
- [Python] Ubuntu 安装/卸载 python
- react---之下拉菜单默认选中的值始终不变的问题
- LayuiAdmin 滚动条设置问题解决
- Java语言程序设计(基础篇)第十版 第一章复习题答案
- 基于Web服务的物联网-WoT(Web of Things)
- dispatch_barrier_GCD学习之dispatch_barrier_async详解
- 我们的宇宙,在某种意义上,是最好的一个
- 又一个布局利器, CSS 伪类 :placeholder-shown
- 晚睡原来是一种病——拖延症
- 实现:您必须使用微信内置浏览器访问本页面! 的功能