一 .我们知道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 长连接事例相关推荐

  1. java Socket长连接

    java socekt 同步套节字编程主要用到java.net.Socket类,通常情况下我们需要socket的长连接模式.其次就是在连接的另一端断开之后需要及时响应. 对于连接的判断,socket提 ...

  2. java socket长连接怎么维持_socket长连接的维持

    import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date;/** * 维持连接的消息对 ...

  3. java Socket 长连接 心跳包 客户端 信息收发 demo

    今天写了个socket的测试小程序,代码如下 import java.io.IOException; import java.io.InputStream; import java.io.Output ...

  4. Java实现SSL Socket长连接

    一.单向认证 1.生成服务端密钥(配置了jdk的环境变量即可用keytool命令) 命令:keytool -genkey -keystore server_ks.jks -storepass serv ...

  5. android端 socket长连接 架构

    看过包建强的<App研发录>之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及socket相 ...

  6. java前端长连接框架_Java如何实现长连接

    实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个维持连接包的. 如果,长时间未发送维持连接包,服务端程序将断开连接. 客户端: Client通过持有Socket的对象,可以随时(使 ...

  7. 【Socket】关于socket长连接的心跳包

    TCP的socket本身就是长连接的,那么为什么还要心跳包呢? 在smack里有个30s发送一个空消息的线程,同样关于心跳包(keepalive) 据网络搜索到的资料解释如下 内网机器如果不主动向外发 ...

  8. socket 长链接linux,手把手教你写 Socket 长连接

    原标题:手把手教你写 Socket 长连接 8点43分打卡 就是真爱 本文转载自公众号 玉刚说,由玉刚说写作平台[1]提供写作赞助 原作者:水晶虾饺[2] 版权声明:本文版权归微信公众号玉刚说所有,未 ...

  9. 手把手教你写 Socket 长连接

    本文由玉刚说写作平台[1]提供写作赞助 原作者:水晶虾饺[2] 版权声明:本文版权归微信公众号 玉刚说 所有,未经许可,不得以任何形式转载 本篇我们先简单了解一下 TCP/IP,然后通过实现一个 ec ...

最新文章

  1. 基于相机和低分辨率激光雷达的三维车辆检测
  2. 并发编程中一种经典的分而治之的思想!!
  3. 2012体感发展加速,微软再添新对手
  4. 【常见问题】Can not perform this action after onSaveInstanceState
  5. Golang 匿名结构体及测试代码编写技巧
  6. Mongodb数据库(1.mongodb的介绍(非关系型数据库)下载与安装(Windows10))
  7. 探索停车黑科技,知位停车破局停车难题!
  8. 通过QQ或者QQ帮助别人学习Lync之一
  9. centos7卸载mysql数据库,CentOS7 安装卸载MySQL
  10. python十大装b语法_Python 十大语法
  11. [Python] Ubuntu 安装/卸载 python
  12. react---之下拉菜单默认选中的值始终不变的问题
  13. LayuiAdmin 滚动条设置问题解决
  14. Java语言程序设计(基础篇)第十版 第一章复习题答案
  15. 基于Web服务的物联网-WoT(Web of Things)
  16. dispatch_barrier_GCD学习之dispatch_barrier_async详解
  17. 我们的宇宙,在某种意义上,是最好的一个
  18. 又一个布局利器, CSS 伪类 :placeholder-shown
  19. 晚睡原来是一种病——拖延症
  20. 实现:您必须使用微信内置浏览器访问本页面! 的功能

热门文章

  1. win10 chrome被毒霸2345劫持主页处理过程与结果
  2. 经典蓝牙和低功耗蓝牙的区别
  3. JS判断对象是否为空对象的几种方法
  4. php敏感词过滤的一个方法
  5. Ubuntu修改屏幕(尺寸/分辨率)大小
  6. Openharmony应用NAPI详解--进阶篇2
  7. 解决Linux无法创建新用户和/home目录下无法创建新目录的问题,或者无权限创建用户目录问题mkdir: cannot create directory ‘ ’: Permissi
  8. 【FPGA】实战之按键消抖
  9. CTF—RGB三原色
  10. sed命令详解与示例