Java实现Socket聊天室

一、网络编程是什么?

在网络通信协议下,不同计算机上运行的程序,进行数据传输。

  • 应用场景:即时通讯、网游对战、金融证券、国际贸易、邮件、等等。

不管是什么场景,都是计算机与计算机之间通过网络进行数据传输。

  • Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。

二、常见的软件架构?

  1. 常见的软件架构有哪些?

    CS/BS。 即Client/Server 和 Browser/Server模式

  2. 通信的软件架构CS/BS的各有什么优缺点和区别?

    CS:客户端服务端模式都需要开发客户端

    BS:浏览器服务器模式不需要开发客户端

    CS:适合定制专业化的办公类软件:IDEA、网游

    BS:适合移动互联网应用,可以在任何地方随时访问系统

三、网络编程三要素?

  • IP:设备在网络中的地址,是唯一的标识
  • 端口号:应用程序在设备中唯一标识
  • 协议:数据在网络中传输的规则,常见的协议游UDP、TCP、HTTP、HTTPS、FTP

四、Socket编程(Java)

Socket(套接字)使用TCP提供了两台计算机之间的通信机制。客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立的时候,服务器会创建一个Socket对象。客户端和服务器可以通过对Socket对象写入和读取来进行通信。

java.net.Socket类代表一个套接字,并且java.net.ServerSocket类为服务器程序提供了一种监听客户端,并与他们建立连接的机制。

以下步骤在两台计算机之间使用Socket建立TCP连接出现:

  • 服务器实例化一个ServerSocket对象,表示通过服务器端口通信。(ServerSocket本质就是监听端口等待Socket对象连接
  • 服务器调用ServerSocket类的accept()方法,该方法将一直等待,直到一个客户端连接到服务器上给定的端口。
  • 服务器ServerSocket监听等待连接的过程中,客户端创建一个Socket对象,并指定该Socket要连接到的服务器的名称端口
  • Socket类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。
  • 在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。

在这里插入图片描述

  1. 连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
  2. TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送。

五、ServerSocket类的方法

服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。

ServerSocket 类有四个构造方法:

序号方法描述
1public ServerSocket(int port) throws IOException 创建监听特定端口的服务器套接字。
2public ServerSocket(int port, int backlog) throws IOException 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
3public ServerSocket(int port, int backlog, InetAddress address) throws IOException 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
4public ServerSocket() throws IOException 创建非绑定服务器套接字。

创建非绑定服务器套接字。 如果 ServerSocket 构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。

这里有一些 ServerSocket 类的常用方法:

序号方法描述
1public int getLocalPort() 返回此套接字在其上侦听的端口。
2public Socket accept() throws IOException 侦听并接受到此套接字的连接。
3public void setSoTimeout(int timeout) 通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。
4public void bind(SocketAddress host, int backlog) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。

六、Socket 类的方法

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept() 方法的返回值。

Socket 类有五个构造方法.

序号方法描述
1public Socket(String host, int port) throws UnknownHostException, IOException. 创建一个流套接字并将其连接到指定主机上的指定端口号。
2public Socket(InetAddress host, int port) throws IOException 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
3public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程主机上的指定远程端口。
4public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程地址上的指定远程端口。
5public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字

当 Socket 构造方法返回,并没有简单的实例化了一个 Socket 对象,它实际上会尝试连接到指定的服务器和端口。

下面列出了一些感兴趣的方法,注意客户端和服务器端都有一个 Socket 对象,所以无论客户端还是服务端都能够调用这些方法。

序号方法描述
1public void connect(SocketAddress host, int timeout) throws IOException 将此套接字连接到服务器,并指定一个超时值。
2public InetAddress getInetAddress() 返回套接字连接的地址。
3public int getPort() 返回此套接字连接到的远程端口。
4public int getLocalPort() 返回此套接字绑定到的本地端口。
5public SocketAddress getRemoteSocketAddress() 返回此套接字连接的端点的地址,如果未连接则返回 null。
6public InputStream getInputStream() throws IOException 返回此套接字的输入流。
7public OutputStream getOutputStream() throws IOException 返回此套接字的输出流。
8public void close() throws IOException 关闭此套接字。

例子(一):Socket 实例

1. 服务端

如下的 MySocketServer 是一个服务端程序,该程序通过 socket 连接到服务器并发送一个请求,然后等待一个响应。

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class MySocketServer extends Thread{private ServerSocket serverSocket;public MySocketServer(int port)throws IOException {//创建ServerSocket监听端口portserverSocket = new ServerSocket(port);//设置等待时间:10000毫秒没有监听到Socket连接该端口就报错serverSocket.setSoTimeout(10000);}public void run(){try{//ServerSocket等待连接,链接成功就创建一个与客户端对等通信的socketSocket server = serverSocket.accept();System.out.println("客户"+server.getLocalAddress()+"连接成功");//获取Socket的输入流输出流DataInputStream inputStream = new DataInputStream(server.getInputStream());DataOutputStream outputStream = new DataOutputStream(server.getOutputStream());while(true){//从流中获取信息String msg = inputStream.readUTF();//当客户端传递的信息为ends时,结束。if(msg.equals("ends")) break;//服务端显示流中的信息System.out.println(msg);}server.close();}catch(Exception ex){ex.printStackTrace();}}public static void main(String[] args){Scanner scanner = new Scanner(System.in);try{System.out.println("请输入服务端绑定端口:");//运行线程让服务端异步运行这样可以让主程序继续干自己的事Thread t = new MySocketServer(scanner.nextInt());t.run();}catch(Exception ex){ex.printStackTrace();}}
}

2. 客户端

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class MySocketClient{public static void main(String[] args){try{Scanner keyboard = new Scanner(System.in);System.out.println("请输入连接主机的IP地址:");String host = keyboard.nextLine();System.out.println("输入主机"+host+" 的端口号:");int port = keyboard.nextInt();//创建Socket并尝试连接 IP=host && 端口=port的服务端Socket client = new Socket(host,port);InputStream in = client.getInputStream();OutputStream out = client.getOutputStream();DataInputStream inputStream = new DataInputStream(in);DataOutputStream outputStream = new DataOutputStream(out);while(true){String msg = keyboard.nextLine();outputStream.writeUTF(msg);//当输入了ends时,客户端关闭socket,服务端也关闭socket,二者结束通信。if(msg.equals("ends"))break;}client.close();}catch(Exception ex){ex.printStackTrace();};}
}

3. 测试结果

在这里插入图片描述

例子(二):聊天室

1. 服务端

  • 服务端使用while循环的添加Socket用户
  • 每个用户有自己独立的线程(异步性:使各个用户可以同时输出输入的同时服务端能够继续监听端口)

在这里插入图片描述

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;public class ChatRoomServer{private static ServerSocket serverSocket;private static ArrayList<Socket> clientList = new ArrayList<Socket>();public static void main(String[] args){try{serverSocket = new ServerSocket(8888);while(true){Socket client = serverSocket.accept();clientList.add(client);//TODO:开启客户端线程,进行异步聊天ClientThread ct = new ClientThread(client,clientList);ct.start();}}catch(Exception ex){ex.printStackTrace();}finally {try{if(serverSocket != null)serverSocket.close();}catch(Exception ex){ex.printStackTrace();}}}
}class ClientThread extends Thread{private Socket client = null;private ArrayList<Socket> clientList;public ClientThread(Socket s,ArrayList<Socket>ss){client = s;clientList = ss;}public void run(){DataInputStream input = null;DataOutputStream output =  null;try{input = new DataInputStream(client.getInputStream());String rec = null;String send = null;while(true){if(!client.isClosed()){rec = input.readUTF();System.out.println("服务端接收到数据:"+rec);clientList.trimToSize();String[] param = rec.split("&");//将输入进行一些封装if("$start$".equals(param[1])){send = param[0] + "进入聊天室";}else{send = param[0] + "说:  " + param[1];}//将非取消信号的数据发送出去if(!("$ends$".equals(param[1]))){for(Socket socket : clientList){if(!socket.isClosed()){output = new DataOutputStream(socket.getOutputStream());output.writeUTF(send);}}}else{for(Socket socket : clientList){if(socket!= client && !socket.isClosed()){output = new DataOutputStream(socket.getOutputStream());output.writeUTF(param[0]+"已退出聊天室");}}output = new DataOutputStream(client.getOutputStream());output.writeUTF("$ends$");client.close();input.close();output.close();}}}}catch(Exception ex){ex.printStackTrace();}}
}

2. 客户端

在这里插入图片描述

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;public class ChatRoomClient {public static final String ip = "127.0.0.1";public static final int port = 8888;public Socket socket = null;public DataInputStream input = null;public DataOutputStream output = null;public Scanner keyboard = new Scanner(System.in);public String send;public String name;public void start(){try{System.out.println(" ################ 欢迎进入Socket聊天室 ################ ");System.out.println("输入您在聊天室的昵称: ");name = keyboard.nextLine();socket = new Socket(ip,port);input = new DataInputStream(socket.getInputStream());output = new DataOutputStream(socket.getOutputStream());send = name + "&$start$";System.out.println(" ################ 进入聊天室成功 ################ ");System.out.println("如需退出聊天室,输入'$ends$'即可....");output.writeUTF(send);//TODO: 编写聊天的线程MsgThread mt = new MsgThread(output,name,input);mt.start();while(true){String rec = input.readUTF();if("$ends$".equals(rec)){System.out.println(" ################ 退出聊天室成功 ################ ");input.close();output.close();socket.close();System.exit(0);}else{System.out.println(rec);}}}catch(Exception ex){ex.printStackTrace();}finally {try{if(socket!= null){socket.close();input.close();output.close();}}catch (Exception ex){ex.printStackTrace();}}}public static void main(String[] args){ChatRoomClient client = new ChatRoomClient();client.start();}
}
class MsgThread extends Thread{private DataInputStream input;private DataOutputStream output;private Scanner keyboard = new Scanner(System.in);public static String name;public MsgThread(DataOutputStream o,String n,DataInputStream i){output = o;input = i;name = n;}public void run(){ChatRoomClient client = new ChatRoomClient();try{while(true){String send = name+"&" + keyboard.nextLine();output.writeUTF(send);}}catch(Exception ex){ex.printStackTrace();}finally {System.out.println("sfef");}}
}

3. 测试结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/209661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试之接口测试自动化(详解版)

本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接口测试领域的一些方法和心得&#xff0c;希望大家一起讨论和分享&#xff0c;内容包括但不仅限于&#xff1a; 服务端接口测试介绍接口测试自动化介绍接口测试自动化实践关于接口测试自动化的思考…

质量工程化,交付快速化

质量和速度之间权衡让人很难取舍&#xff0c;而通过推进质量工程&#xff0c;以系统化的方式识别和优化系统痛点&#xff0c;可以帮助团队构建既快又好的精益软件生产系统。原文: Quality Engineered, Speed Delivered 所有人都想要更快的速度。 但需要解决复杂问题: 权衡质量会…

(二)五种最新算法(SWO、COA、LSO、GRO、LO)求解无人机路径规划MATLAB

一、五种算法&#xff08;SWO、COA、LSO、GRO、LO&#xff09;简介 1、蜘蛛蜂优化算法SWO 蜘蛛蜂优化算法&#xff08;Spider wasp optimizer&#xff0c;SWO&#xff09;由Mohamed Abdel-Basset等人于2023年提出&#xff0c;该算法模型雌性蜘蛛蜂的狩猎、筑巢和交配行为&…

线上盲盒小程序,开启互联网盲盒时代

近年来&#xff0c;盲盒经济在国内非常火爆&#xff0c;各类盲盒品牌层出不穷&#xff0c;深受国内外年轻人、消费者的喜爱。 目前&#xff0c;根据数据显示&#xff0c;盲盒市场不仅在线下异常火热&#xff0c;线上盲盒也是成为了大众的新选择。各类电商平台中盲盒的成交额更…

Esxi7Esxi8设置VMFSL虚拟闪存的大小

Esxi7Esxi8设置VMFSL虚拟闪存的大小 ESXi7,8 默认安装会分配一个 VMFSL(VMFS-L)(Local VMFS)很大空间(120G), 感觉很浪费, 实际给 8G 就可以了, 最少 6G , 经实验,给2G没法安装 . Esxi7是虚拟闪存的 修改的方法是: 在安装时修改 设置 autoPartitionOSDataSize8192 在cdromBoo…

快捷切换raw页面到repo页面-Raw2Repo插件

Raw2Repo By Rick &#x1f4d6;快捷切换代码托管平台raw页面到repo页面 &#x1f517;github链接 https://github.com/rickhqh/Raw2Repo ✨Features 功能&#xff1a; ✅单击 Raw2Repo 插件按钮&#xff0c;即可跳转到相应的代码仓库页面。✅支持 GitHub、Gitee、GitCode …

spring boot整合mybatis进行部门管理管理的增删改查

部门列表查询&#xff1a; 功能实现&#xff1a; 需求&#xff1a;查询数据库表中的所有部门数据&#xff0c;展示在页面上。 准备工作&#xff1a; 准备数据库表dept&#xff08;部门表&#xff09;&#xff0c;实体类Dept。在项目中引入mybatis的起步依赖&#xff0c;mysql的…

【ET8】1.ET8入门-运行指南

主要学习网址 论坛地址为&#xff1a;https://et-framework.cn Git地址为&#xff1a;GitHub - egametang/ET: Unity3D Client And C# Server Framework 官方QQ群 : 474643097 项目检出 检出项目切换到release8.0分支 GitHub地址&#xff1a;GitHub - egametang/ET: Unity…

[足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-5Laplace Transform of Convolution卷积的拉普拉斯变换

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-数学基础Ch0-5Laplace Transform of Convolution卷积的拉普拉斯变换 Laplace Transform : X ( s ) L [ x ( t ) ] ∫ 0 ∞ x ( t ) e − s t d t X\left( s \right) \mathcal{L} \left[ x\lef…

基于Swin_Transformer的图像超分辨率系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 随着科技的不断发展&#xff0c;图像超分辨率技术在计算机视觉领域中变得越来越重要。图像超分辨率是指通过使用计算机算法将低分辨率图像转换为高分辨率图像的过…

AI:91-基于深度学习的手写数学表达式识别

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的核心代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新…

51单片机的时钟电路与时序以及 复位电路和电源模式

51单片机的时钟电路与时序以及 复位电路和电源模式 本文主要涉及51单片机的时钟电路以及相关时序的知识&#xff0c;也讲解了了51单片机的复位电路以及电源模式。 文章目录 51单片机的时钟电路与时序以及 复位电路和电源模式一、时钟电路与时序1、 时钟电路设计1.1 内部时钟方式…

导入PR的视频画面是黑屏的怎么办?

在现代视频编辑领域中&#xff0c;越来越多的人使用Adobe Premiere Pro来编辑和制作视频&#xff0c;但是在某些情况下&#xff0c;用户可能需要透明背景的视频进行创作&#xff0c;那么如何创作透明背景的视频呢&#xff1f; 要制作具有透明背景的视频&#xff0c;我们需要使…

如何赢得并留住订阅者:12 个必须尝试的订阅营销策略

Netflix、Hubspot、Spotify 和 Slack 都是流行的基于订阅的服务&#xff0c;您可能每天都会使用它们&#xff0c;无论是工作还是娱乐。这些例子表明&#xff0c;订阅业务模式深受 SaaS 创业者的青睐。 这种模式的吸引力很容易理解&#xff0c;特别是考虑到订阅市场预计到 2025…

C //例10.5 有一个磁盘文件,内有一些信息。要求第1次将它的内容显示在屏幕上,第2次把它复制到另一文件上。

C程序设计 &#xff08;第四版&#xff09; 谭浩强 例10.5 例10.5 有一个磁盘文件&#xff0c;内有一些信息。要求第1次将它的内容显示在屏幕上&#xff0c;第2次把它复制到另一文件上。 IDE工具&#xff1a;VS2010 Note: 使用不同的IDE工具可能有部分差异。 代码块 方法&a…

mysql支持的整数类型、各类型整数能够表示的数值范围

MySQL :: MySQL 8.2 Reference Manual :: 11.1.2 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT mysql支持的整数有&#xff1a;TINYINT、SMALLINT、MEDIUMINT、INT&#xff08;INT和INTEGER是同义词&#xff09;、BIGINT&#xff0c;各…

【C#】序列化和反序列化,以及System.Text.Json和Newtonsoft.Json比较

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 序列化和反序列化&#xff0c;在实际项目开发过程中用的最多。特别是有对接接口的小伙伴就深有体会。本篇文章就简单聊聊这个知识点。 目录 一、基本概念1.1、序列化1.2反序列化1.3、举例…

AI 赋能 | 智能制造的 AI 算法开发和工程实现

谈到智能制造、智慧工厂&#xff0c;愿景是美好的&#xff0c;借助计算机视觉技术和 AI 算法&#xff0c;为自动化生产线赋予环境感知的能力&#xff0c;从而改善工艺流程&#xff0c;提高生产效率。但是&#xff0c;随着柔性化生产的需求增长&#xff0c;产线的布局调整和功能…

Docker三 | 数据卷

目录 Docker数据卷简介 添加数据卷的命令 容器数据卷的继承 Docker数据卷简介 Docker容器产生的数据&#xff0c;如果不备份&#xff0c;当容器实例删除后&#xff0c;容器中的数据也会消失&#xff0c;为了保存数据可以在Docker中使用数据卷。Docker数据卷是宿主机的一个可以…

vue3中子组件调用父组件的方法

<script lang"ts" setup>前提 父组件&#xff1a; 子组件&#xff1a; const emit defineEmits([closeson]) 在子组件的方法中使用&#xff1a; emit(closeson)