Socket 实现聊天功能

注:本文来自:简书: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 

时间: 2024-08-30 08:21:06

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

使用socket实现聊天功能

public class Service { //服务器 public static void main(String[] args) { ServerSocket serverSocket=null; Socket socket=null; //既然是 双方的通信 输入和输出流 必须有 OutputStream os=null; InputStream is=null; BufferedReader br=null; byte [] buf=new byte[1024]; int say; S

socket实现聊天功能(二)

WebSocket协议是建立在HTTP协议之上,因此创建websocket服务时需要调用http模块的createServer方法.将生成的server作为参数传入socket.io的方法中.如下代码: var express = require('express'); var app = express(); var server = require('http').createServer(app); var io = require('socket.io')(server); var po

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

说到聊天,那么其实就是传输数据,把自己写的东西传给自己想发送的那么人.我总结一下传输有三种方式 1:就是我们常见的数据库传输 2:就是文件(流)传输 3:就是socket传输 今天我们说的wcf实现聊天其实是基于socket的聊天功能(QQ聊天发展到今天肯定是很牛的了,但是最初肯定也是这样的思想) 今天我先说说基于WCF聊天的原理 1:需要一个回调函数(当用户发送的时候会吧信息回调给客户端本身) 2:需要一个委托(把服务器传来的信息显示给前台) 3:需要一个触发点击事件(目的是为了触发把发送信息

Socket编程一实现简易的聊天功能以及文件传输

干程序是一件枯燥重复的事,每当感到内心浮躁的时候,我就会找小说来看.我从小就喜爱看武侠小说,一直有着武侠梦.从金庸,古龙,梁羽生系列到凤歌(昆仑),孙晓(英雄志)以及萧鼎的(诛仙)让我领略着不一样的江湖. 如果你有好看的武侠系列小说,给我留言哦.题外话就扯这么多了,接着还是上技术. 看看今天实现的功能效果图: 可以这里使用多台手机进行通讯,[凤歌]我采用的服务器发送消息. 是不是只有发送消息,有些显得太单调了.好,在发送消息的基础上增加文件传输.后期会增加视频,音频的传输,增加表情包.那一起来看

Java UDP实现聊天功能代码

我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务器端需要阻塞式等待客户端的连接.而UDP则是可以直接向目的地址的目的端口上发送数据包,由于它只负责发送出去就好,不管对方是否正确接受到与否,所以当网络性能不好时它容易出现丢包的问题.(注意:UDP是基于数据报为单位进行传输的,而TCP是一种基于流进行传输的) 但是UDP很好的模拟了我们呢平时聊天的方式,可以很好的实现连续多次发送和接受,也就是简单的QQ聊天的功能. 现在来简要介绍Java中有关UDP编程相关的类:

Socket.IO聊天室

小编心语:大家过完圣诞准备迎元旦吧~小编在这里预祝大家元旦快乐!!这一次要分享的东西小编也不是很懂啊,总之小编把它拿出来是觉地比较稀奇,而且程序也没有那么难,是一个比较简单的程序,大家可以多多试试~ Socket.IO聊天室 简介:Socket.IO实现了实时双向的基于事件的通讯机制.旨在让各种浏览器与移动设备上实现实时app功能,模糊化各种传输机制.下面我们使用Node.js和Socket.IO来做一个简单的聊天室.一.初始化项目 (这个是在实验楼网站的虚拟平台需要实现的~可自动略过这一环节,

linux下基于socket的聊天软件

近期学习linux socket编程.看看unp那本书.顺便写了个类似最简单聊天功能的软件.界面是用qt写的.写下来总结总结吧,假设有问题.欢迎大家和我交流. 模式是C/S模式,server端等待请求.client发送后建立请求.连接用的是tcp不是udp,事实上udp实现更为简单. 一. 环境搭建 我用docker搭了几个虚拟机,详细搭建方式能够參考网上的或我之前写docker的总结:点击打开链接 docker还是非常轻量级的,比一般虚拟机起的快多了. 搭建好docker以后就是主要的先看网络

Linux下p2p的聊天功能实现

Linux下p2p的聊天功能实现细节 Do one thing at a time, and do well. 今天闲着没事,写一个P2P的点对点的聊天功能的小程序,我觉得对网络编程初学者的学习很有用的.二话不说,我先贴代码吧.有几个地方需要考虑清楚.我会在代码的后面写出来.代码的下载文章的末尾. server.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <

MINA 实现聊天功能

原文同步至 http://www.waylau.com/mina-chat/ 在<MINA 快速入门>一文中,我们介绍了如何利用 MINA 快速构建一个 Time Server(时间服务器).在<Netty 实现聊天功能>一文,我们也介绍了如何用 Netty 实现聊天功能.由于 MINA 和 Netty 是同一个作者,架构类似,如果你掌握其中一个,学习另外一个也不是难事.现在我们就用 MINA 来实现聊天功能. 准备 JDK 7+ Maven 3.2.x MINA 2.x Ecli