使用java网络编程模拟简单网络即时通信

通信流程图:

解析:

1.在上图中我们可以看出对于任何一个客户端,都由两部分构成,发送端和接收端(分别由两个线程来维系)

2.客户端在每一次请求链接时都会轮询,向服务器发送请求,服务器发回当前在线列表

3.服务器端使用线程池技术为每一个连接请求创建一个线程去处理。

4.在客户端与服务器之间使用TCP通讯,可靠通信

5.在用户之间使用UDP报文来传输数据。

代码实现:

Chat类:

package cn.csuft.poorguy.homework;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Scanner;import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;public class Chat {Thread sender;Thread receiver;DatagramSocket udpSocket;Socket tcpSocket;public Chat() {try {Scanner cin = new Scanner(System.in);System.out.println("昵称:");String nick = cin.nextLine();//TODD C/StcpSocket = new Socket("127.0.0.1",9000);InputStream in = tcpSocket.getInputStream();OutputStream out = tcpSocket.getOutputStream();//发送自己的昵称和端口udpSocket = new DatagramSocket();int udpPort = udpSocket.getLocalPort();String msg = new String(nick+","+udpPort);out.write(msg.getBytes());out.flush();//接收在线用户的列表byte []buf = new byte[1024];int size = in.read(buf);String json = new String(buf,0,size);//HashMap<String, Integer> users = new Gson().fromJson(json,HashMap.class);HashMap<String, Integer> users = JSON.parseObject(json, HashMap.class);System.out.println("在线列表 :  "+users);//double p = users.get(nick).doubleValue();//把用户列表传给SenderTasksender = new Thread(new SendTask(udpSocket,users,tcpSocket));receiver = new Thread(new ReceiverTask(udpSocket));sender.start();receiver.start();} catch (SocketException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {Chat chat = new Chat();}}

  

ChatServer类:

package cn.csuft.poorguy.homework;import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ChatServer {ServerSocket serverSocket;int serverPort = 9000;ExecutorService pool;Map<String, Integer> users = new HashMap<String, Integer>();public ChatServer() {pool = Executors.newCachedThreadPool();}public void start() {System.out.println("服务器启动:。。。。");try {serverSocket = new ServerSocket(serverPort);while(true) {Socket socket = serverSocket.accept();OnlineService onlineService = new OnlineService(socket,users);pool.execute(onlineService);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {ChatServer chatServer = new ChatServer();chatServer.start();}
}

  

OnlineService类:

package cn.csuft.poorguy.homework;import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;public class OnlineService implements Runnable{Socket socket;Map<String, Integer> users;public OnlineService() {// TODO Auto-generated constructor stub}public OnlineService(Socket socket, Map<String, Integer> users) {this.socket = socket;this.users = users;}@Overridepublic void run() {try (InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream()){byte []buf = new byte[1024];int size = in.read(buf);String msg = new String(buf,0,size);//解析出msg中的nick信息String nick = msg.split(",")[0];int port = Integer.parseInt(msg.split(",")[1]);//将nick与端口放入在线列表中users.put(nick, port);//String json = new Gson().toJson(users);String json = JSON.toJSONString(users);System.out.println(json);out.write(json.getBytes());out.flush();} catch (Exception e) {// TODO: handle exception}}
}

  

ReceiveTask类:

package cn.csuft.poorguy.homework;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class ReceiverTask implements Runnable {DatagramSocket socket = null;public ReceiverTask() {// TODO Auto-generated constructor stub}public ReceiverTask(DatagramSocket socket) {this.socket = socket;}@Overridepublic void run() {String msg = null;byte []buf = new byte[1024*8];do {DatagramPacket packet = new DatagramPacket(buf, buf.length);try {socket.receive(packet);byte []data = packet.getData();msg = new String(data,0,packet.getLength());System.out.println("收到: "+msg);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} while (!msg.equalsIgnoreCase("bye"));System.out.println("接收端关闭");}}

  

SendTask类:

package cn.csuft.poorguy.homework;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Scanner;import com.alibaba.fastjson.JSON;public class SendTask implements Runnable {HashMap<String, Integer> users;DatagramSocket socket = null;Socket tcpSocket;public SendTask() {// TODO Auto-generated constructor stub}public SendTask(DatagramSocket socket, HashMap<String, Integer> users, Socket tcpSocket) {this.socket = socket;this.users = users;this.tcpSocket = tcpSocket;}@Overridepublic void run() {String msg = null;Scanner cin = new Scanner(System.in);DatagramPacket packet = null;while (true) {GetUsersFromServer();System.out.println("输入接收方:");String nick = cin.nextLine();if (users.containsKey(nick)) {do {int port = users.get(nick);System.out.print("发送:");msg = cin.nextLine();byte[] data = msg.getBytes();try {// 创建数据包packet = new DatagramPacket(data, data.length, InetAddress.getByName("127.0.0.1"), port);// 发送socket.send(packet);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} while (!msg.equalsIgnoreCase("bye"));System.out.println("发送结束");} else {System.out.println("该用户不在线");}}}private void GetUsersFromServer() {// TODD C/Stry {tcpSocket = new Socket("127.0.0.1", 9000);InputStream in = tcpSocket.getInputStream();OutputStream out = tcpSocket.getOutputStream();// 发送自己的昵称和端口int udpPort = socket.getLocalPort();String ss = new String("######" + "," + udpPort);out.write(ss.getBytes());out.flush();// 接收在线用户的列表byte[] buf = new byte[1024];int size = in.read(buf);String json = new String(buf, 0, size);// HashMap<String, Integer> users = new Gson().fromJson(json,HashMap.class);users = JSON.parseObject(json, HashMap.class);System.out.println("在线列表 :  " + users);} catch (UnknownHostException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}

注意:

这里服务器发回的在线列表使用的是fastJson转换成JSON的,在这个过程中遇到了一些晓得问题,之前选用的Gson,但是发现Gson会默认将int转成double,会出现一些错误,所以改用fastJson,建议以后可以直接使用fastJson避免出现类似的错误。

转载于:https://www.cnblogs.com/PoorGuy/p/10403838.html

使用java网络编程模拟简单网络即时通信相关推荐

  1. Java网络编程学习——简单模拟在线聊天

    Java网络编程学习--简单模拟在线聊天 学了java网络,也是该做个小案例来巩固一下了. 本次案例将使用UDP和多线程模拟即时聊天,简单练练手. 1.前提知识 需要知道简单的IO流操作,以及简单的U ...

  2. 简单网络聊天程序java_基于Java实现hello/hi简单网络聊天程序

    Socket简要阐述 Socket的概念 Socket的英文原义是"孔"或"插座". 在网络编程中,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连 ...

  3. eNSP模拟简单网络环境

    eNSP模拟简单网络环境 实验环境 用ensp搭建图中拓扑,其中cloud1所在的网络为vmnet1,VMware Workstation中开启一台windows7计算机,网络桥接在VMnet1,IP ...

  4. 【Java 18】网络编程 - 概述、网络编程要素、IP和端口号、网络协议、TCP、UDP、URL

    网络编程 - 概述.网络编程要素.IP和端口号.网络协议.TCP.UDP.URL 网络编程 1 网络编程概述 2 网络通信要素概述 3 通信要素1:IP和端口号 3.1 内容 3.2 InetAddr ...

  5. 同软件多个线程设置不同ip_5-13网络编程(附带多线程死锁,线程通信)

    0513多线程 死锁 当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步.这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁 线程通信 生产者消费者模式 模拟街道案例 wai ...

  6. 网络编程二-LINUX网络IO模型

    目录 前言:网络编程里通用常识 一.同步和异步与阻塞和非阻塞 同步和异步 阻塞和非阻塞 两者的组合 二.五种I/O模型 阻塞I/O模型 非阻塞IO模型 IO复用模型 信号驱动IO 异步IO模型 5个I ...

  7. 【JavaSe】网络编程篇(一) 网络编程入门

    JavaSe·网络编程篇(一) 网络编程入门 1. 软件结构 C/S结构:全称为Client/Server结构,是指客户端和服务器结构.常见程序有QQ.百度网盘等软件 B/S结构 :全称为Browse ...

  8. 网络编程笔记之网络编程入门

    网络编程的概念 网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包,在接收端按照规定好的协议把包进行解析,从而提取出对应的信息,达到通信的目的.中间最主要的就是数据包的组装,数据包的过滤 ...

  9. 【练习题】构造方法 编写Java程序,模拟简单的计算器。

    package day09; /*1.[练习题]构造方法 编写Java程序,模拟简单的计算器. 定义名为Number的类,其中有两个整型数据成员n1和n2,应声明为私有.编写构造方法,赋予n1和n2初 ...

最新文章

  1. Android实例RSS客户端开发(1)
  2. Eclipse中阿里JAVA代码规范插件(P3C)的安装及使用
  3. 流式机器学习算法的入门和认知
  4. 如果__name__ =='__main__':在Python中怎么办?
  5. 【Elasticsearch】Elasticsearch 优化写入流程实现NRT近实时(filesystem cache,refresh)
  6. Java获取Object属性值
  7. 设置DBGridEH自适应列宽的最好方法
  8. ASCII码表 0~127
  9. SSH框架之-hibernate 三种状态的转换
  10. FreeSWITCH之日志级别
  11. 2021-01-29
  12. Kali Linux上最佳安全测试工具
  13. CSP-S2020总结
  14. 安徽大学计算机专硕学几年,安徽大学专业硕士学制几年
  15. 用python画中国象棋棋盘
  16. 关于丢番图方程x^2+y^2=n
  17. Android原生App跳转到React Native App
  18. 放大器构成电压跟随器 proteus仿真 TLV2252
  19. 西湖大学全披露:68位顶级科学家加盟,已获捐资35亿,最小捐赠者12岁
  20. 斩杀线计算大师 三元一次方程解

热门文章

  1. java lua_如何在Java中使用Lua脚本语言
  2. SSD目标检测:tensorflow 版本调试以及出现错误的解决方法
  3. 各大协作机器人厂商人机安全协作方式(HRC)简介
  4. python处理多行字符串_python多行字符串
  5. QT核心机制3:信号与槽
  6. 手机连接fiddler上网
  7. python图像处理(prewitt算子)
  8. 解决win10 的代理 IE可以正常代理,但chrome无法使用
  9. 如何利用状态机编程实现启保停控制(含Stateflow模型介绍)
  10. XSS(跨站脚本攻击)原理详解(内含攻击实例)