Java使用Socket简单通讯详解
作者:Aputonos 发布时间:2023-11-03 02:54:43
标签:Java,socket
Java实现基于Socket的简单通信
一.ServerSocket
1.使用JavaFX写的小界面,方便观察客户端连接情况
TextArea ta = new TextArea();
Scene scene = new Scene(new javafx.scene.control.ScrollPane(ta), 450, 200);
primaryStage.setTitle("Server");
primaryStage.setScene(scene);
primaryStage.show();
2.创建ServerSocket并处理客户端连接并显示客户端基本信息
两个客户端连接后进行通信,未能实现动态处理。
new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(8000);
Platform.runLater(() -> {
ta.appendText(new Date() + " : Server started at " + "\n");
ta.appendText(new Date() + " : wait to persons to join the chat" + "\n");
});
while (true){
Socket person1 = serverSocket.accept();
number++;
InetAddress inetAddress1 = person1.getInetAddress();
Platform.runLater(() -> {
ta.appendText(new Date() + ": Person" + number + "joined the chat" + "\n");
ta.appendText(new Date() + ": Person" + number + "'s host name is " + inetAddress1.getHostName() + "\n");
ta.appendText(new Date() + ": Person" + number + "'s host address is " + inetAddress1.getHostAddress() + "\n");
ta.appendText(new Date() + ": wait for Person2 " + "\n");
});
Socket person2 = serverSocket.accept();
number++;
InetAddress inetAddress2 = person2.getInetAddress();
Platform.runLater(() -> {
ta.appendText(new Date() + ": Person" + number + "joined the chat" + "\n");
ta.appendText(new Date() + ": Person" + number + "'s host name is " + inetAddress2.getHostName() + "\n");
ta.appendText(new Date() + ": Person" + number + "'s host address is " + inetAddress2.getHostAddress() + "\n");
ta.appendText(new Date() + ": Start the chat " + "\n");
});
new Thread(new HandleChat(person1,person2)).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
3.新建Handle类处理接收发送两个客户端的消息
只实现了一人一句的效果,没有实现一人连续发送消息对方也能正确接收。
class HandleChat implements Runnable{
Socket person1;
Socket person2;
public HandleChat(Socket person1,Socket person2){
this.person1 = person1;
this.person2 = person2;
}
@Override
public void run() {
try {
DataInputStream fromPerson1 = new DataInputStream(person1.getInputStream());
DataOutputStream toPerson1 = new DataOutputStream(person1.getOutputStream());
DataInputStream fromPerson2 = new DataInputStream(person2.getInputStream());
DataOutputStream toPerson2 = new DataOutputStream(person2.getOutputStream());
while (true){
String passage1 = fromPerson1.readUTF();
toPerson2.writeUTF(passage1);
String passage2 = fromPerson2.readUTF();
toPerson1.writeUTF(passage2);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
思考后将HandleChat类中对两个客户端的接收发送消息处理放在两个线程中,就可以实现两个客户端自由通信。
new Thread(() -> {
while (true) {
try {
String passage2 = fromPerson2.readUTF();
toPerson1.writeUTF(passage2);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
while (true) {
try {
String passage1 = fromPerson1.readUTF();
toPerson2.writeUTF(passage1);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
二.Socket
1.同样的编写一个客户端界面
BorderPane pane = new BorderPane();
pane.setPadding(new Insets(5));
pane.setStyle("-fx-border-color: green");
pane.setLeft(new Label("Enter a radius: "));
TextField tf = new TextField();
tf.setAlignment(Pos.BASELINE_RIGHT);
pane.setCenter(tf);
BorderPane mainPane = new BorderPane();
TextArea ta = new TextArea();
mainPane.setCenter(new ScrollPane(ta));
mainPane.setTop(pane);
Scene scene = new Scene(mainPane,450,200);
primaryStage.setTitle("Client");
primaryStage.setScene(scene);
primaryStage.show();
2.创建Socket连接客户端并获取输入输出流
try {
// 创建一个连接服务器端的Socket
Socket socket = new Socket("localhost",8000);
// 获得输入输出流
toServer = new DataOutputStream(socket.getOutputStream());
fromServer = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
3.添加编辑框监听处理消息发送
// 编辑框事件监听
tf.setOnAction(e ->{
String passage = tf.getText().trim();
tf.clear();
try {
toServer.writeUTF(passage);
toServer.flush();
ta.appendText("Me " + ": " + passage + "\n");
} catch (IOException e1) {
e1.printStackTrace();
}
});
4.创建新线程从服务器上接收消息
// 新线程从服务器读取信息
new Thread(() -> {
while (true) {
try {
String passage = fromServer.readUTF();
ta.appendText("He : " + passage + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
三.测试
四.总结
1.原理流程
2.不足之处
只是简单实现了静态两客户端聊天的功能,并且只能够第一个链接上的用户先发送消息,且一人发送消息后只能等待接收另一个人的消息后才能再次发送消息。之后的时间希望能加以改进。
到此这篇关于Java使用Socket简单通讯详解的文章就介绍到这了,更多相关Java使用Socket简单通讯内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://blog.csdn.net/qq_43463475/article/details/85039512
0
投稿
猜你喜欢
- https://www.jb51.net/article/114838.htm这篇文章很详细的介绍了JS的跨域,给出的解决方案是spring
- 业务场景通常微服务对于用户认证信息解析有两种方案在 gateway 就解析用户的 token 然后路由的时候把 userId 等相关信息添加
- 本文实例为大家分享了自定义Drawable实现圆形和圆角的具体代码,供大家参考,具体内容如下圆形package com.customview
- 场景我们团队现在面临着多端数据接口对接的问题,为了解决这个问题我们定义了接口对接的规范,前端(安卓,Ios,web前端)和后端进行了数据的格
- 不同的浏览器会把cookie文件保存在不同的地方以下是C# WebBrowser控件cookies的存放路径C:\Users\{你的帐号名}
- 本文主要介绍了关于单例模式的一些问题,想学习C#单例模式的同学们可以看一看,还是有些帮助c#中的单例模式单例模式是指在设计一个类时,保证在运
- 一、内存池基础知识1、什么是内存池1.1 池化技术池化技术是计算机中的一种设计模式,主要是指:将程序中经常要使用的计算机资源预先申请出来,由
- 对象的读写使用ObjectInputStream和ObjectOutputStream读写对象(序列化与反序列化)。只有字节流没有字符流.类
- 直接上代码新建DecimalInputTextWatcher类继承TextWatcher (代码可直接复制使用) import androi
- Eureka大白话解析笔记补录:1.Eureka 介绍Spring Cloud Eureka 是 Spring Clou
- 一、DataSource首先大家要清楚DataSource属于MyBatis三层架构设计的基础层 然后我们来看看具体的实现。在数据持久层中
- 首先,通过代码定义一个委托和下面三个示例将要调用的方法:public delegate int AddHandler(int a,int b
- String ipArr[]={"127.0.0.1","127.0.0.2"}; &n
- 前面一篇有说道如何在MyEclipse中搭建maven项目,这里将继续介绍如何在搭建好的基础maven项目中引入我们常用的javaweb框架
- Java类成员变量的默认值基本数据类型作为类的成员变量时可以不赋予初值,在方法中输出也不会报错。下面我们看看我们的八种数据类型的默认值是什么
- 如果对空的对象进行操作,就会造成意外错误。所以我们在使用对象前,一般会进行非空判断接下来介绍我知道的三种判断非空方法:1、if判断这个最直接
- **请注意!请注意!!!**今天讲给大家讲解非常“有用”的设计模式,解释器模式!!!设计模式有三大种类,一种是创建型模式,一种是结构型模式,
- 1、效果展示2、布局文件<?xml version="1.0" encoding="utf-8"
- 使用环境项目环境:Idea 2020.2.3、 Maven 3.6.3 、springboot 2.1.4本人在创建springboot项目
- 可以静态绑定数据源,这样就自动为DataGridView控件添加 相应的行。假如需要动态为DataGridView控件添加新行,方法有很多种