注:本文来自:简书:jianshu

作者:jijs
链接:http://www.jianshu.com/p/7c0722a8b66f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

需要提前了解知识点
java.net.Socket 解析
java.net.ServerSocket 解析

使用socket实现一个端对端聊天系统。

消息的格式为:消息长度(int)+消息内容

通过消息长度来进行socket分包,防止读取出现半包、粘包等问题。

服务端代码

  1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6
7 /**
8 * @author jijs
9 * @date 2017-08-14
10 */
11 public class ChatServer {
12 public static void main(String[] args) throws Exception {
13 start();
14 }
15
16 public static void start() throws Exception {
17 try (ServerSocket ss = new ServerSocket(9000);
18 Socket s = ss.accept();
19 InputStream is = s.getInputStream();
20 OutputStream os = s.getOutputStream();) {
21
22 //开启一个线程,实时读取对方发过来的消息
23 new Thread(ChatUtil.receive(is)).start();
24
25 //从控制台输入消息,并发送
26 ChatUtil.send(os);
27
28 } catch (IOException e) {
29 e.printStackTrace();
30 }
31
32 }
33
34 }

客户端代码

  1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.net.Socket;
5
6 /**
7 * @author jijs
8 * @date 2017-08-14
9 */
10 public class ChatClient {
11
12 public static void main(String[] args) throws Exception {
13 start();
14 }
15
16 public static void start() {
17 try (Socket s = new Socket("127.0.0.1", 9000);
18 InputStream is = s.getInputStream();
19 OutputStream os = s.getOutputStream();) {
20
21 //开启一个线程,实时读取对方发过来的消息
22 new Thread(ChatUtil.receive(is)).start();
23
24 //从控制台输入消息,并发送
25 ChatUtil.send(os);
26
27 } catch (IOException e) {
28 e.printStackTrace();
29 }
30
31 }
32
33 }

聊天工具类

  1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.util.Scanner;
5
6 /**
7 * @author jijs
8 * @date 2017-08-14
9 */
10 public class ChatUtil {
11
12 /**
13 * 读取对方发过来的消息
14 * @param is
15 * @return
16 */
17 public static Runnable receive(final InputStream is) {
18 return new Runnable() {
19 public void run() {
20 while (true) {
21 try {
22 // 当前消息总字节长度
23 int returnLen = ChatUtil.readLen(is);
24 byte[] b = new byte[returnLen];
25 int readSize = 0; // 每次读取的字节数
26 int count = 0; // 总读取的字节数
27 while (count < returnLen && (readSize = is.read(b)) != -1) {
28 count += readSize;
29 }
30 String str = new String(b, 0, readSize);
31 System.out.println("接收:" + str);
32 } catch (IOException e) {
33 e.printStackTrace();
34 break;
35 }
36 }
37 }
38 };
39 }
40
41 /**
42 * 从控制台接收用户输入,发送消息给对方
43 * @param os
44 */
45 public static void send(final OutputStream os) {
46 Scanner scan = new Scanner(System.in);
47 while (true) {
48 try {
49 String s = scan.nextLine();
50 byte[] data = s.getBytes();
51 int len = data.length;
52 os.write(ChatUtil.int2byte(len));
53 os.write(data);
54 os.flush();
55 } catch (IOException e) {
56 e.printStackTrace();
57 break;
58 }
59 }
60 scan.close();
61 }
62
63 /**
64 * 读取消息长度
65 * 消息格式为:消息长度+消息内容
66 * @param is
67 * @return
68 * @throws IOException
69 */
70 public static int readLen(InputStream is) throws IOException {
71 int b1 = is.read();
72 int b2 = is.read();
73 int b3 = is.read();
74 int b4 = is.read();
75 int len = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
76 return len;
77 }
78
79 /**
80 * int 转 byte[] 数组
81 * @param len
82 * @return
83 */
84 public static byte[] int2byte(int len) {
85 byte[] b = new byte[4];
86 b[0] = (byte) (len >> 24);
87 b[1] = (byte) (len >> 16 & 0XFF);
88 b[2] = (byte) (len >> 8 & 0XFF);
89 b[3] = (byte) (len & 0XFF);
90 return b;
91 }
92 }
93

Socket 实现聊天功能的更多相关文章

  1. socket实现聊天功能(二)

    socket实现聊天功能(二) WebSocket协议是建立在HTTP协议之上,因此创建websocket服务时需要调用http模块的createServer方法.将生成的server作为参数传入so ...

  2. 使用socket实现聊天功能

    public class Service { //服务器 public static void main(String[] args) { ServerSocket serverSocket=null ...

  3. 我们一起学习WCF 第九篇聊天功能

    说到聊天,那么其实就是传输数据,把自己写的东西传给自己想发送的那么人.我总结一下传输常见的有三种方式 1:就是我们常见的数据库传输 2:就是文件(流)传输 3:就是socket传输 今天我们说的wcf ...

  4. Socket.IO聊天室~简单实用

    小编心语:大家过完圣诞准备迎元旦吧~小编在这里预祝大家元旦快乐!!这一次要分享的东西小编也不是很懂啊,总之小编把它拿出来是觉地比较稀奇,而且程序也没有那么难,是一个比较简单的程序,大家可以多多试试~ ...

  5. Android 基于Socket的聊天应用(二)

    很久没写BLOG了,之前在写Android聊天室的时候答应过要写一个客户(好友)之间的聊天demo,Android 基于Socket的聊天室已经实现了通过Socket广播形式的通信功能. 以下是我写的 ...

  6. Linux下p2p的聊天功能实现

    Linux下p2p的聊天功能实现细节 Do one thing at a time, and do well. 今天闲着没事,写一个P2P的点对点的聊天功能的小程序,我觉得对网络编程初学者的学习很有用 ...

  7. windows phone 8.1开发:socket通信聊天

    本例用WPF程序做服务器端,windows phone程序做客户端.我们使用基于UDP协议的Socket通信.更多关于socket信息请查看:http://msdn.microsoft.com/zh- ...

  8. Spring 学习——基于Spring WebSocket 和STOMP实现简单的聊天功能

    本篇主要讲解如何使用Spring websocket 和STOMP搭建一个简单的聊天功能项目,里面使用到的技术,如websocket和STOMP等会简单介绍,不会太深,如果对相关介绍不是很了解的,请自 ...

  9. 使用websocket实现在线聊天功能

    很早以前为了快速达到效果,使用轮询实现了在线聊天功能,后来无意接触了socket,关于socket我的理解是进程间通信,首先要有服务器跟客户端,服务的启动监听某ip端口定位该进程,客户端开启socke ...

随机推荐

  1. office 激活教程

    首先在我的百度云里下载:http://pan.baidu.com/share/link?shareid=2200272243&uk=1985086665激活工具安装包 如果遇到问题,可以加我Q ...

  2. CPU密集型和I/O密集型区别

    CPU密集型 一些进程绝大多数时间在计算上,称为计算密集型(CPU密集型)computer-bound.一些大量循环的代码(例如:图片处理.视频编码.人工智能等)就是CPU密集型. I/O密集型 有一 ...

  3. selenium_采集药品数据1_采集第一页表格

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  4. 配置GitLab Push 自动触发Jenkins构建

    配置GitLab Push 自动触发Jenkins构建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客是对之前的笔记:https://www.cnblogs.com/yin ...

  5. JavaWeb应用和Servlet

    JavaWeb应用的生命周期是由Servlet容器来控制的.包括三个阶段: 1.启动阶段:加载Web应用的有关数据,创建ServletContest对象,对Filter(过滤器)和一些Servlet进 ...

  6. FASTREPORT COM/ActiveX报表如何保存到C++项目中?

    可以的. VC++ : ... IStream * pStream;CreateStreamOnHGlobal(NULL, true, &pStream);pStream->AddRef ...

  7. urllib和urllib2之间的区别

    urllib和urllib2都是接受URL请求的相关模块,但是提供了不同功能. urllib2可以接受一个Request类的实例来设置URL请求的headers,urllib仅可以接受URL.这意味着 ...

  8. Bleve代码阅读(一)——新建索引

    引言 Bleve是Golang实现的一个全文检索库,类似Lucene之于Java.在这里通过阅读其代码,来学习如何使用及定制检索功能.也是为了通过阅读代码,学习在具体环境下Golang的一些使用方式. ...

  9. luogu P2662 牛场围栏

    传送门 因为一个木板可以切掉最多\(m\),所以可以先预处理哪些长度的木板可用,开个桶,然后对\([l-m,l]\)打标记,再把打了标记的数取出来 假设可用长度\(a_1,a_2,,,a_n\)从小到 ...

  10. 永久修改MySQL字符集(适用Mysql5.5、Mysql5.6、Mysql5.7以上)

    在my.ini文件里添加三个参数: 1.在[client]下添加 default-character-set=utf8 2.在[mysqld]下添加 character-set-server=utf8 ...