日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简易命令行界面的C/S聊天室

發布時間:2024/3/13 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简易命令行界面的C/S聊天室 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


最近幾天復習了下java網絡編程socket使用我覺得雖然下面的內容很基礎但是如果想要做出個好的東西想要快速掌握以后要學習的先要把基礎打牢

如果基礎打得好那么將來學習新的知識會很快,其實都是同理的。

如果大神能發揮下,拓展下完善下功能那就更好了,請在下面留下您的想法我會一直維護我的這些文章。

TCP?協議基礎

IP協議是Internet的使用的一個關鍵協議,全稱是Internet?Protocol,即Internet協議通常簡稱IP協議通過IP協議,從而使Internet成為一個允許連接不同類型計算機的不同操作系統的網絡。如果想要兩臺計算機通信那么就要使用相同的語言?那么就是用IP協議但是只保證計算機能發送接受分組數據,IP協議負責將消息從一個主機發送到另一個主機,消息在傳送過程中被分割成包。但是這樣只是解決了他們之間的發送和接收數據但是還不能解決數據分組在數據傳輸過程中出現的問題。所以就需要使用TCP協議以保證提供可靠并且無差錯的通信服務。

TCP協議是面向連接的端對端的協議。這是因為他對兩臺計算機之間的鏈接起到了重要的作用建立的鏈接用于發送和接收數據的虛擬鏈路

TCP和IP協議的功能雖然不盡相同,也可以分開使用,但是他們是在同一時期作為一個協議來設計的,并且在功能上也是互補的。只有兩者結合起來才能保證internet在復雜的環境下正常的運行凡事要連接到internet的計算機都必須同時安裝和使用這兩個協議因此唱吧這兩個協議叫做TCP/IP協議

使用serverSocket創建TCP服務器端

在兩個通信實體之間沒有建立虛擬鏈路之前必須先有一個通信實體先做出“主動姿態”主動地接受來自其他實體的連接請求。Java中接收其他的通信實體連接請求的類是ServerSocket,serverSocket用于監聽來自socket端的連接,如果沒有連接,他將一直處于等待狀態,serverSocket包含一個監聽來自客戶端請求的方法

Socket?accept():如果接收到一個客戶端的Socket的鏈接的請求,該方法返回一個與客戶端對應的socket否則該方法一直處于等待狀態線程也被阻塞

為了創建serversocket對像,提供了如下幾個構造器

serverSocket(int?port)指定的端口創建一個serverSocket對像該端口應該有一個有效的端口整數

serverSocket(int?port,int?backlog):增加一個用來改變連接隊列長度的參數backlog

當serverSocket使用完畢后,應使用serverSocket的close()方法關閉該serverSocket。在通常情況下

?

服務器不用改制接受一個客戶端的請求,而應該不斷地接受來自客戶端的所有的請求,所以java程序通常會循環的不斷的調用serverSocket的accept()方法

使用socket進行通信

客戶端通常可以使用socket的構造器連接到指定的服務器,socket通常可以使用給定的兩個構造器連接到相應的主機或者是相應的IP地址的服務器這樣就能實現對話

--

加入多線程

前面的Server和Client只是進行了簡單的通信操作:服務器端接收到客戶端的連接之后,服務器端向客戶端輸出了一個字符串,而客戶但也只是讀取服務器端的字符串后就退出了,實際應用中的客戶端可能根據需要和服務器端保持長時間通信,即服務器端需要不斷的讀取客戶端數據,并向客戶端寫入數據;客戶端也需要不斷的讀取服務器端的數據,并向服務器端寫入數據。

在使用傳統的BufferReader的readLine()方法讀取數據時,在該方法成功返回之前,線程被阻塞,程序無法執行。考慮到這個因素,服務器端應該為每個Socket啟動一個線程,每個線程負責與一個客戶端進行通信

客戶端讀取服務器端數據的縣城同樣會被阻塞,所以系統應該單獨啟動一個線程。該線程專門負責讀取服務器端的數據。

現在考慮實現一個命令行的界面的C/S聊天室應用,服務器端應該包含多個線程,每個Socket對應一個線程,該線程負責讀取Socket對應輸入流的數據。并將讀取到的數據向每個Socket輸出流發送一次(將一個客戶端的數據廣播給其他客戶端)需要在服務器端使用list保存所有的Socket

服務器端的實現:

<span style="font-size:18px;"><span style="font-size:18px;">package com.example.administrator.openinternet;import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List;/*** Created by Administrator on 2015/7/23.* 服務器端的程序*/ public class javaSocket {public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());public static void main (String [] args) throws IOException {ServerSocket ss = new ServerSocket(30000);while(true){Socket s = ss.accept();socketList.add(s);new Thread( new ServerThread(s)).start();}} } </span></span>
服務器端的線程類:

<span style="font-size:18px;"><span style="font-size:18px;">package com.example.administrator.openinternet;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.SocketException;/*** Created by Administrator on 2015/7/23.* 服務器端的線程*/ public class ServerThread implements Runnable {Socket s = null;BufferedReader br = null;public ServerThread(Socket s){this.s = s ;try {br = new BufferedReader(new InputStreamReader(s.getInputStream()));//創建并讀取流} catch (IOException e) {e.printStackTrace();}}/*** Starts executing the active part of the class' code. This method is* called when a thread is started that has been created with a class which* implements {@code Runnable}.*/@Overridepublic void run(){try{String content = null;while ((content = readFromClient())!=null){for(Socket s:javaSocket.socketList){PrintStream ps = new PrintStream(s.getOutputStream());}}}catch (IOException e){e.printStackTrace();}}private String readFromClient() {try{return br.readLine();}catch (IOException e) {e.printStackTrace();javaSocket.socketList.remove(s);//移除socketList中的數據三}return null;} } </span></span> 客戶端實現:

<span style="font-size:18px;">package com.example.administrator.openinternet;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket;/*** Created by Administrator on 2015/7/23.* 我的客戶端的程序*/ public class MyClient {public static void main(String [] args) throws IOException{Socket s = new Socket("127.0.0.1",30000);new Thread( new ClientThread(s)).start();PrintStream ps = new PrintStream(s.getOutputStream());String line = null;BufferedReader br = new BufferedReader( new InputStreamReader(System.in));while ((line = br.readLine())!=null){ps.println(line);}} } </span>
客戶端線程:

<span style="font-size:18px;">package com.example.administrator.openinternet;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket;/*** Created by Administrator on 2015/7/23.* 客戶端的線程*/ public class ClientThread implements Runnable {private Socket s ;BufferedReader br = null;public ClientThread(Socket s) throws IOException {this.s = s ;br = new BufferedReader(new InputStreamReader(s.getInputStream()));}/*** Starts executing the active part of the class' code. This method is* called when a thread is started that has been created with a class which* implements {@code Runnable}.*/@Overridepublic void run(){try{String content = null;while ((content = br.readLine())!=null){System.out.println(content);}}catch (Exception e){e.printStackTrace();}} } </span>
這就實現了簡單的回話,其實可以繼續擴展比如實現客戶端和服務器端的數據的傳遞過幾天更新過來


總結

以上是生活随笔為你收集整理的简易命令行界面的C/S聊天室的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。