多人群聊聊天室java_#java 聊天室(一)—— 实现一个简单Telnet多人群聊聊天室...
#java ? ?聊天室(一)—— ?實現一個簡單Telnet多人群聊聊天室
學習本文須要先準備的知識點:隊列(或數組)、類與對象、線程、InputStream和OutputStream的使用。java
1.前期準備(新知識點講解)
(1)、認識Telnet數組
a、關于Telnet服務器
Telnet協議是TCP/IP協議族中的一員,是Internet遠程登錄服務的標準協議和主要方式。它為用戶提供了在本地計算機上完成遠程主機工做的能力。在終端使用者的電腦上使用telnet程序,用它鏈接到服務器。終端使用者能夠在telnet程序中輸入命令,這些命令會在服務器上運行,就像直接在服務器的控制臺上輸入同樣。能夠在本地就能控制服務器。要開始一個telnet會話,必須輸入用戶名和密碼來登陸服務器。Telnet是經常使用的遠程控制Web服務器的方法。網絡
b、telnet的工做過程:函數
(a)、本地與遠程主機創建鏈接。該過程其實是創建一個TCP鏈接,用戶必須知道遠程主機的Ip地址或域名;學習
(b)、將本地終端上輸入的用戶名和口令及之后輸入的任何命令或字符以NVT(Net Virtual Terminal)格式傳送到遠程主機。該過程其實是從本地主機向遠程主機發送一個IP數據包;this
(c)、將遠程主機輸出的NVT格式的數據轉化為本地所接受的格式送回本地終端,包括輸入命令回顯和命令執行結果;.net
(d)、最后,本地終端對遠程主機進行撤消鏈接。該過程是撤銷一個TCP鏈接。線程
(以上關于telnet的內容摘自百度百科)code
咱們須要作的,就是寫一個服務器,使用戶可以鏈接上咱們的服務器,并且咱們的服務器可以對用戶發送的消息進行處理。
(2)、BufferedReader類:用于從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。此類的對象建立時,須要傳入一個InputStream對象。
此類的部分相關方法:
read(); // 讀取單個字符。
readLine(); //讀取一個文本行,程序運行到這里時須要用戶輸入,將用戶輸入的數據讀取。
例如:
bs = new BufferedReader(new InputStreamReader(in));
String name = bs.readLine();
(3)、ServerSocket類:此類實現服務器套接字。服務器套接字等待請求經過網絡傳入。它基于該請求執行某些操做,而后可能向請求者返回結果。簡而言之,就是在指定端口建立一個服務器。此類的對象建立時,須要傳入的數字就是端口。
此類的相關方法:
accept(); //偵聽并接受到此套接字的鏈接。此方法在鏈接傳入以前一直阻塞。即接受用戶鏈接,在用戶未鏈接時程序會在此暫停。其返回值是一個Socket對象。
例如:
//在6666端口建立一個服務器,等待用戶鏈接(雖然建立了,但不會對用戶的鏈接做出反應)。
ServerSocket sever = new ServerSocket(6666);Socket sk = sever.accept();
(4)、Socket類:此類實現客戶端套接字(也能夠就叫“套接字”)。套接字是兩臺機器間通訊的端點。 能夠利用Socket對象與客戶端進行交互。
此類的相關方法:
getOutputStream(); //返回此套接字的輸出流。即返回用戶端的輸出流,能夠借助此輸出流顯示傳遞給用戶的信息。
getInputStream(); //返回此套接字的輸入流。即返回用戶端的輸入流,能夠借助此輸入流獲取用戶端的輸入信息。
2.思路分析
(1)、創建一個服務器,實現相應的端口,在用戶鏈接的時候啟動一個線程,用于獲取用戶的輸入和輸出,為了可以讓多個用戶鏈接,能夠將偵聽用戶鏈接的代碼放在一個while(true)循環里面(偵聽的語句在沒有用戶鏈接的時候會在此暫停,不用擔憂死循環形成的程序卡頓等問題):
//創建一個Message對象的隊列,用于儲存用戶的信息,Message對象將會在后面介紹
static ArrayList m = new ArrayList<>();
static ServerSocket sever;
public static void main(String[] args) {
try {
//建立一個服務器,實現6666端口
sever = new ServerSocket(6666);
System.out.println("服務器已開啟。");
while (true) {
//偵聽用戶鏈接,沒有用戶鏈接的時候會在此停留
Socket sk = sever.accept();
//有用戶鏈接,建立一個線程控制用戶的輸入輸出
Sever ss = new Sever(m,sk);
Thread ts = new Thread(ss);
//啟動線程
ts.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
(2)、創建一個對象,儲存用戶輸入的信息,而且執行改用戶的輸出操做
public class Message {
//msg用于儲存用戶輸入的消息
private String msg;
//name儲存用戶姓名
private String name;
//判斷用戶有沒有輸入
private boolean isNewPut = true;
//判斷用戶是否是第一次進入
private boolean isNewJoin = true;
//用于控制線程的開始中止
private boolean start = true;
public void setName(String name) {
this.name = name;
}
public boolean getStart() {
return start;
}
public String getName() {
return name;
}
public Message() {
msg = new String();
}
//獲取用戶輸入的信息,將判斷是否有用戶輸入的boolean值改成true,這個值為true時,下面介紹的的Together線程將會向全部用戶輸出此用戶的消息
public void addMsg(String msg) {
this.msg = msg;
isNewPut = true;
}
public String getMsg() {
return msg;
}
public void setIsNewPut(boolean s) {
isNewPut = s;
}
public boolean getIsNewPut() {
return isNewPut;
}
public void setIsNewJoin(boolean j) {
isNewJoin = j;
}
public boolean getIsNewJoin() {
return isNewJoin;
}
//用戶退出時,將strat、isNewPut改為false
public void exit() {
start = false;
isNewPut = false;
}
}
(3)、編寫控制用戶輸入輸出的線程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Sever implements Runnable {
//用于儲存用戶的Message隊列
private ArrayList msg;
private Socket sk;
private Message m;
//count可用做區分用戶的索引
private int count;
private OutputStream out;
private BufferedReader bs;
private InputStream in;
public Sever(ArrayList msg, Socket sk, int count) {
this.msg = msg;
this.sk = sk;
this.count = count;
}
public void run() {
recieve();
}
//將用戶的輸出傳給全部用戶,并在全部用戶的控制臺輸出
public void setMsg(BufferedReader bs) throws IOException {
while (msg.get(count).getStart()) {
String strMsg = bs.readLine();
if (strMsg != null)
msg.get(count).setMsgAll(msg.get(count).getName() + " said:" + strMsg + "\r\n");
}
}
//接受用戶輸入并處理
public void recieve() {
try {
//獲取用戶控制臺的輸入輸出流
out = sk.getOutputStream();
in = sk.getInputStream();
out.write("welcome!Please enter your username:\r\n".getBytes());
bs = new BufferedReader(new InputStreamReader(in));
//獲取用戶輸入,若是用戶沒有按回車,程序會在此暫停
String name = bs.readLine();
out.write(("Your username is:" + name + "\r\n").getBytes());
//初始化Message對象,并將用戶的姓名、輸出流、消息儲存進用戶的Message對象
m = new Message(name, out, msg);
//用于區分用戶的索引,好比第一個用戶登陸時這個值為0,第二個用戶時這個值為2
count = msg.size();
//將Message對象m存入Message隊列的第count處
msg.add(count, m);
//在全部用戶的控制臺輸入XXX已經上線
msg.get(count).setMsgAll(name + " is on line.\r\n");
//此函數會循環獲取用戶輸入并在全部用戶的控制臺輸出
setMsg(bs);
//跳出上面的函數說明用戶已經下線,則關閉全部的流、用戶對應的Socket對象,從Message隊列移除上線的用戶
out.close();
in.close();
sk.close();
msg.remove(count);
} catch (IOException e) {
e.printStackTrace();
}
}
}
總結
以上是生活随笔為你收集整理的多人群聊聊天室java_#java 聊天室(一)—— 实现一个简单Telnet多人群聊聊天室...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谈一谈url实现文件下载
- 下一篇: 异步电机三相电流滞环矢量控制