Java使用Socket簡(jiǎn)單通訊詳解
Java實(shí)現(xiàn)基于Socket的簡(jiǎn)單通信
一.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.創(chuàng)建ServerSocket并處理客戶端連接并顯示客戶端基本信息
兩個(gè)客戶端連接后進(jìn)行通信,未能實(shí)現(xiàn)動(dòng)態(tài)處理。
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類處理接收發(fā)送兩個(gè)客戶端的消息
只實(shí)現(xiàn)了一人一句的效果,沒(méi)有實(shí)現(xiàn)一人連續(xù)發(fā)送消息對(duì)方也能正確接收。
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類中對(duì)兩個(gè)客戶端的接收發(fā)送消息處理放在兩個(gè)線程中,就可以實(shí)現(xiàn)兩個(gè)客戶端自由通信。
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.同樣的編寫一個(gè)客戶端界面

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.創(chuàng)建Socket連接客戶端并獲取輸入輸出流
try {
// 創(chuàng)建一個(gè)連接服務(wù)器端的Socket
Socket socket = new Socket("localhost",8000);
// 獲得輸入輸出流
toServer = new DataOutputStream(socket.getOutputStream());
fromServer = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
3.添加編輯框監(jiān)聽處理消息發(fā)送
// 編輯框事件監(jiān)聽
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.創(chuàng)建新線程從服務(wù)器上接收消息
// 新線程從服務(wù)器讀取信息
new Thread(() -> {
while (true) {
try {
String passage = fromServer.readUTF();
ta.appendText("He : " + passage + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
三.測(cè)試

四.總結(jié)
1.原理流程

2.不足之處
只是簡(jiǎn)單實(shí)現(xiàn)了靜態(tài)兩客戶端聊天的功能,并且只能夠第一個(gè)鏈接上的用戶先發(fā)送消息,且一人發(fā)送消息后只能等待接收另一個(gè)人的消息后才能再次發(fā)送消息。之后的時(shí)間希望能加以改進(jìn)。
到此這篇關(guān)于Java使用Socket簡(jiǎn)單通訊詳解的文章就介紹到這了,更多相關(guān)Java使用Socket簡(jiǎn)單通訊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中隨機(jī)鹽值+雙重SHA256加密實(shí)戰(zhàn)
本文主要介紹了SpringBoot中隨機(jī)鹽值+雙重SHA256加密實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
微信企業(yè)號(hào) 根據(jù)錯(cuò)誤碼返回錯(cuò)誤信息類封裝
這篇文章主要介紹了微信企業(yè)號(hào) 根據(jù)錯(cuò)誤碼返回錯(cuò)誤信息類封裝的相關(guān)資料,需要的朋友可以參考下2016-10-10
SpringCloud實(shí)現(xiàn)基于RabbitMQ消息隊(duì)列的詳細(xì)步驟
在Spring Cloud框架中,我們可以利用RabbitMQ實(shí)現(xiàn)強(qiáng)大而可靠的消息隊(duì)列系統(tǒng),本篇將詳細(xì)介紹如何在Spring Cloud項(xiàng)目中集成RabbitMQ,并創(chuàng)建一個(gè)簡(jiǎn)單的消息隊(duì)列,感興趣的朋友一起看看吧2024-03-03
SpringBoot 利用thymeleaf自定義錯(cuò)誤頁(yè)面
這篇文章主要介紹了SpringBoot 利用thymeleaf自定義錯(cuò)誤頁(yè)面,幫助大家更好的理解和使用springboot 框架,感興趣的朋友可以了解下2020-11-11
SpringBoot前后端傳輸加密設(shè)計(jì)實(shí)現(xiàn)方案
這篇文章主要給大家介紹了關(guān)于SpringBoot前后端傳輸加密設(shè)計(jì)實(shí)現(xiàn)方案的相關(guān)資料,包括數(shù)據(jù)加密方案、解密傳輸數(shù)據(jù)實(shí)現(xiàn)方案和響應(yīng)數(shù)據(jù)加密實(shí)現(xiàn)方案,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-11-11
Java并發(fā)(Runnable+Thread)實(shí)現(xiàn)硬盤文件搜索功能
這篇文章主要介紹了Java并發(fā)(Runnable+Thread)實(shí)現(xiàn)硬盤文件搜索,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01

