Java——网络编程(实现基于命令行的多人聊天室)
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
目錄:
1.ISO和TCP/IP分層模型
2.IP協(xié)議
3.TCP/UDP協(xié)議
4.基于TCP的網(wǎng)絡(luò)編程
5.基于UDP的網(wǎng)絡(luò)編程
6.基于TCP的多線程的聊天室的實(shí)現(xiàn)
?
1.ISO和TCP/IP分層模型:
OSI分層模型(Open System Interconnection)為“開放系統(tǒng)互連參考模型”。為國際標(biāo)準(zhǔn)化組織ISO提出。
TCP/IP分層模型更和實(shí)際應(yīng)用相貼近。
對應(yīng)關(guān)系如上圖。其中TCP/IP體系中,網(wǎng)絡(luò)層對應(yīng)IP(Internet Protocol),傳輸層對應(yīng)TCP(Transmiss Control Protocl)。
分層思想:只有相鄰的兩層才能夠進(jìn)行信息的交互。如:應(yīng)用層需要傳輸信息時(shí),會(huì)將信息交給傳輸層,傳輸層會(huì)將信息進(jìn)行包裝,并傳遞給網(wǎng)絡(luò)層;網(wǎng)絡(luò)層會(huì)將信息再次包裝,在傳遞給物理+數(shù)據(jù)鏈路層。而別的計(jì)算機(jī)需要解析信息時(shí),也需要反向?qū)訉咏馕?#xff0c;才能獲得應(yīng)用所需的信息。
?
2.ip協(xié)議:
負(fù)責(zé)提供獨(dú)一無二的ip地址。
傳送信息時(shí)除了需要ip地址,也需要端口號(hào)。ip地址相當(dāng)于選擇連接互聯(lián)網(wǎng)上的某臺(tái)計(jì)算機(jī),而端口號(hào)相當(dāng)于選擇連接一臺(tái)計(jì)算機(jī)上的某個(gè)應(yīng)用。
端口號(hào)可以從0-65535,通常分三類:①公認(rèn)端口:0-1023,http默認(rèn)80端口;②注冊端口:1024-49151,通常應(yīng)用程序應(yīng)該使用這個(gè)范圍內(nèi)的端口;③動(dòng)態(tài)/私有端口:49152-65535,應(yīng)用程序不會(huì)主動(dòng)會(huì)用這些端口,一般是動(dòng)態(tài)分配的。
端口號(hào)又分tcp和udp:比如tcp888和udp888是不一樣的。
?
?
3.TCP/UDP協(xié)議:
tcp可靠但是慢(因?yàn)橛写_認(rèn)):如銀行登錄。
udp不可靠但是快:如發(fā)qq語音,如果丟包也就是語音茲拉幾聲;cf網(wǎng)絡(luò)問題導(dǎo)致閃現(xiàn);
如果網(wǎng)絡(luò)在不太擠的話,udp也比較可靠,如果擠則肯能被路由器丟失,這就是丟包。
?
Socket:
一般網(wǎng)絡(luò)編程也稱為socket編程。
關(guān)于網(wǎng)絡(luò)編程的類一般都在java.net:其下有兩個(gè)類一個(gè)socket(client),一個(gè)serversocket(server)分別用來實(shí)現(xiàn)雙向鏈接的client端和server端
這都是對tcp而言,因?yàn)閷τ趗dp而言沒有嚴(yán)格意義上的server和client。
建立連接時(shí)所需的尋址信息為遠(yuǎn)程計(jì)算機(jī)的ip地址和端口號(hào)(Port number),ip地址相當(dāng)于尋找計(jì)算機(jī),而端口號(hào)尋找同一計(jì)算機(jī)上的不同應(yīng)用程序。
?
4.基于TCP的網(wǎng)絡(luò)編程:
ServerSocket是堵塞式的(accept方法是阻塞式的),因?yàn)橛袝r(shí)有Client訪問有時(shí)沒有,所以SercerSocket不間斷運(yùn)行,等待Client連接。
Client和Server交流通過“流”。
readUTF也是阻塞式的。會(huì)導(dǎo)致其他client在阻塞期間連接不上。
代碼如下:
//TCPSevrver.javaimport java.io.DataInputStream; import java.io.InputStream; import java.net.*;public class TCPserver {public static void main(String[] args) throws Exception {ServerSocket ss=new ServerSocket(6666); while(true) {//為了滿足服務(wù)器不間斷的條件Socket s=ss.accept();//在server也建立一個(gè)socket,用來接收client來的申請DataInputStream dis=new DataInputStream(s.getInputStream());//從輸入流里獲取數(shù)據(jù)System.out.println(dis.readUTF());//打印數(shù)據(jù)dis.close();//關(guān)閉輸入流s.close();//關(guān)閉Client的連接}} } //TCPClient.javaimport java.io.DataOutputStream; import java.io.OutputStream; import java.net.*;public class TCPclient {public static void main(String[] args) throws Exception {Socket s=new Socket("127.0.0.1", 6666);//創(chuàng)建連接Server的Socket,根據(jù)ip和端口OutputStream os=s.getOutputStream();DataOutputStream dos=new DataOutputStream(os);//輸出流dos.writeUTF("hello server");dos.flush();dos.close();//關(guān)閉輸出流s.close();//關(guān)閉Client的連接} }?
5.基于UDP的網(wǎng)絡(luò)編程
?
6.基于TCP的多線程的聊天室的實(shí)現(xiàn)
思想就是將Service和Client的交互都放入新的線程中。從而使數(shù)據(jù)交互不會(huì)堵塞。
實(shí)現(xiàn)共4個(gè).java文件:
MyServer.java——服務(wù)器主體
ServerThread.java——服務(wù)器為處理單個(gè)Client創(chuàng)建的線程
MyClient.java——客戶端主體
ClientThread.java——Client中實(shí)現(xiàn)等待服務(wù)器發(fā)送聊天內(nèi)容的線程
直接貼代碼:
package TalkRoom;import java.io.IOException; import java.net.*; import java.util.*;public class MyServer {//定義保存所有socket,并將其包裝成線程安全的public static List<Socket> list=Collections.synchronizedList(new ArrayList<>());public static void main(String[] args)throws IOException {// TODO Auto-generated method stubServerSocket ss=new ServerSocket(8888);//如果沒有人連接,就一直堵塞while(true) {Socket s=ss.accept(); //將連接的client保存在s中l(wèi)ist.add(s);//將新的s添加進(jìn)s的list中//每當(dāng)一個(gè)client連接到server,server總會(huì)開啟一個(gè)新的線程與client進(jìn)行服務(wù)new Thread(new ServerThread(s)).start();}}} package TalkRoom;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket;public class ServerThread implements Runnable {private Socket s;BufferedReader br;public ServerThread(Socket s) throws IOException {// TODO Auto-generated constructor stubthis.s=s;//初始化該socket對應(yīng)的輸入流br=new BufferedReader(new InputStreamReader(s.getInputStream()));}@Overridepublic void run() {// TODO Auto-generated method stubtry {String content=null;//采用循環(huán)不斷從socket中讀取客戶端發(fā)送來的數(shù)據(jù)while((content=readFromClient())!=null) {//遍歷list中的每一個(gè)socket//將讀到的content像每一個(gè)socket發(fā)送一次for(Socket s:MyServer.list) {PrintStream ps=new PrintStream(s.getOutputStream());ps.println(content);}}} catch (IOException e) {// TODO: handle exceptione.printStackTrace();}}private String readFromClient() {// TODO Auto-generated method stubtry {return br.readLine();} catch (IOException e) {// TODO: handle exception//捕獲到異常說明該socket已關(guān)閉,則從list中刪除該socketMyServer.list.remove(s);}return null;}} package TalkRoom;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException;public class MyClient {public static void main(String[] args) throws UnknownHostException, IOException {// TODO Auto-generated method stubSocket s=new Socket("127.0.0.1", 8888);//客戶端啟動(dòng)ClientThread線程不斷地從server讀取數(shù)據(jù)new Thread(new ClientThread(s)).start();//獲取該socket對應(yīng)的輸出流PrintStream ps=new PrintStream(s.getOutputStream());String line=null;//不斷地讀取鍵盤輸入的信息BufferedReader br=new BufferedReader(new InputStreamReader(System.in));while((line=br.readLine())!=null) {//將用戶鍵盤輸入的內(nèi)容不斷地輸入到socket的輸出流中ps.println(line);}}} package TalkRoom;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket;public class ClientThread implements Runnable {private Socket s;BufferedReader br;public ClientThread(Socket s) throws IOException {// TODO Auto-generated constructor stubthis.s=s;br=new BufferedReader(new InputStreamReader(s.getInputStream()));}@Overridepublic void run() {// TODO Auto-generated method stubtry {String context=null;while((context=br.readLine())!=null) {System.out.println(context);}} catch (IOException e) {// TODO: handle exceptione.printStackTrace();}}}初步實(shí)現(xiàn)了一個(gè)多人聊天室的功能,雖然沒有圖形界面,但是也能更進(jìn)一步了解多線程以及Server、Client交互的實(shí)現(xiàn)。
轉(zhuǎn)載于:https://my.oschina.net/u/3786691/blog/1673176
總結(jié)
以上是生活随笔為你收集整理的Java——网络编程(实现基于命令行的多人聊天室)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: build怎么调试 react_Reac
- 下一篇: Java5线程并发库之LOCK(锁)CO