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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

在Java中使用Socket模拟客户端和服务端(多线程)

發布時間:2025/5/22 java 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Java中使用Socket模拟客户端和服务端(多线程) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1:Socket與ServerSocket的交互

2.Socket和ServerSocket介紹

Socket

構造函數

Socket()

Socket(InetAddress address, int port)throws UnknownHostException, IOException

Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException

Socket(String host, int port)throws UnknownHostException, IOException(最簡單的連接方式)

Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException

除去第一種不帶參數的之外,其它構造函數會嘗試建立與服務器的連接。如果失敗會拋出IOException錯誤。如果成功,則返回Socket對象。

InetAddress是一個用于記錄主機的類,其靜態getHostByName(String msg)可以返回一個實例,其靜態方法getLocalHost()也可以獲得當前主機的IP地址,并返回一個實例。

Socket(String host, int port, InetAddress localAddress, int localPort)構造函數的參數分別為目標IP、目標端口、綁定本地IP、綁定本地端口。

Socket方法

getInetAddress();??? 遠程服務端的IP地址

getPort();??? 遠程服務端的端口

getLocalAddress()??? 本地客戶端的IP地址

getLocalPort()??? 本地客戶端的端口

getInputStream();??? 獲得輸入流

getOutStream();??? 獲得輸出流

值得注意的是,在這些方法里面,最重要的就是getInputStream()和getOutputStream()了。

Socket狀態

isClosed();???? //連接是否已關閉,若關閉,返回true;否則返回false

isConnect();      //如果曾經連接過,返回true;否則返回false

isBound();???? //如果Socket已經與本地一個端口綁定,返回true;否則返回false

ServerSocket

構造函數

ServerSocket()throws IOException

ServerSocket(int port)throws IOException

ServerSocket(int port, int backlog)throws IOException

ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException

注意點:

1. port服務端要監聽的端口;backlog客戶端連接請求的隊列長度;bindAddr服務端綁定IP

2. 如果端口被占用或者沒有權限使用某些端口會拋出BindException錯誤。譬如1~1023的端口需要管理員才擁有權限綁定。

3. 如果設置端口為0,則系統會自動為其分配一個端口;

4. bindAddr用于綁定服務器IP,為什么會有這樣的設置呢,譬如有些機器有多個網卡。

5. ServerSocket一旦綁定了監聽端口,就無法更改。ServerSocket()可以實現在綁定端口前設置其他的參數。

3.實例前說明

Socket網絡編程主要用于兩臺機器之間的數據傳輸,大致過程為:建立連接→信息傳遞→關閉連接。我們可以理解為服務器(ServerSocket)和客戶端(Socket),服務器提供連接服務,客戶端鏈接服務器。因為服務器需要向多臺客戶端提供服務,所以需要一直保持監聽狀態,不斷地監聽客戶端請求,在這個過程中,ServerSocket一直處于阻斷狀態,直到有客戶端連接,馬上返回一個Socket對象,然后通過IO流傳輸數據,在這個過程中,當有數據傳輸的時候,IO流才被激活,其余時間都處于阻斷狀態,等待數據發送過來,然后進行處理。

注意:

當我們發送數據的時候,必須使用flush()方法,將數據提交,否則只會存在于緩沖中,不會發送數據,有時候即使我們使用flush()方法,也無法從另一臺電腦上讀取到數據,這是因為Socket會將數據先存儲起來,等到數據量達到一定大小的時候,會一起提交(或者這樣理解,flush()會根據換行符’\n’判斷用戶是否完成輸入,如果沒有看到’\n’,Socket認為用戶數據還沒有寫完,仍在保留在緩存池中)所以我們可以在要提交的數據加上’\n’強制提交就可以了。

不過,如果我們沒必要很多的交互,只需要交互一次就可以了,就可以不在乎這些,當關閉Socket的輸入輸出流的時候,Socket會將緩存池中的數據全部提交到另一臺機器。

最后最重要的,當我們用完流的時候,一定要及時關閉,養成良好的習慣。

在下面的實例中,我通過多線程的方式保證服務器和客戶端一直處于數據交互狀態,并且使用線程池的方式維護線程。、

線程類:

package com.best.alivn.socketservice; import java.io.*; import java.net.Socket; import java.util.Scanner;/**讓服務器處理與客戶端通訊放在線程中* Created by Alivn on 2017/3/18.*/ public class SessionThread implements Runnable{private final Socket client;private static Integer Tag=0;public SessionThread(Socket client) {this.client = client;}@Overridepublic void run() {//輸出流PrintWriter writer=null;//獲取客戶端輸入流,得到客戶端發來的消息try {//讀取客戶端的數據//讀取到的一行數據String line=null;//客戶端發來的數據//開啟一個讀線程Thread write_thread= new Thread(new Runnable() {@Overridepublic void run() {//輸入流InputStream inputStream=null;BufferedReader reader=null;try {while (true) {inputStream= client.getInputStream();//為了提高效率,轉換成字符流reader=new BufferedReader(new InputStreamReader(inputStream));String line=null;while ((line=reader.readLine())!=null){System.out.println(line);}}} catch (IOException e) {//流異常 e.printStackTrace();}finally {//關閉流try {inputStream.close();reader.close();} catch (IOException e) {e.printStackTrace();}}}});write_thread.start();//獲取輸出流,往客戶端發送數據writer=new PrintWriter(client.getOutputStream());//客戶端剛連接的時候,客戶端反饋信息String send_msg ="您已成功連接到服務器......--[Server]";writer.println(send_msg);writer.flush();//可以多次發送//從鍵盤輸入while ("1".equals("1")) {Scanner scanner=new Scanner(System.in);send_msg =scanner.nextLine()+"--[Server]";writer.println(send_msg);//注意(我們發送數據的時候,flush方法會提交我們的數據,但是還不會發送,當數據達到一定容量才會發送,// 或者讀到換行符的時候發送) writer.flush();}} catch (IOException e) {//獲取客戶端輸入流失敗 e.printStackTrace();}finally {//關閉流try {client.shutdownInput();client.shutdownOutput();writer.close();} catch (IOException e) {//關閉輸入輸出流失敗 e.printStackTrace();}}} }

服務器類:

package com.best.alivn.socketservice; import scala.actors.threadpool.ExecutorService; import scala.actors.threadpool.Executors; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket;/**服務器* Created by Alivn on 2017/3/18.*/ public class Server {//甚至端口號private final static Integer PORT=8888;//設置開啟的線程數private final static Integer THREAD_SIZE=5;//創建線程池private static ExecutorService executorService=null;public static void main(String[]args){executorService = Executors.newFixedThreadPool(THREAD_SIZE);//創建服務器套接字try {//創建三個線程放入到線程池中....ServerSocket serverSocket=new ServerSocket(PORT);//開啟服務器,一直處于監聽的狀態System.out.println("[Server]:服務器已啟動.........");while (true){//服務器根據端口號,監聽客戶端鏈接,Socket client = serverSocket.accept();System.out.println("[Server]:有客戶端鏈接至服務器.......");//將交互放到線程中SessionThread session=new SessionThread(client);//放入到線程池中 session.run();executorService.execute(session);}} catch (IOException e) {//實例化服務器失敗 e.printStackTrace();}}}客戶端類: package com.best.alivn.socketservice; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner;/**客戶端* Created by Alivn on 2017/3/18.*/ public class Client {private final static String host="localhost";private final static Integer port=8888;public static void main(String[] args) {Socket socket=null;//輸入流BufferedReader reader=null;//創建客戶端對象try {//連接服務器socket=new Socket(host,port);//客戶端剛連接的時候,客戶端反饋信息//輸出流final PrintWriter writer=new PrintWriter(socket.getOutputStream());;String send_msg ="你好,我是小白......--[Client]";writer.println(send_msg);writer.flush();//開啟一個線程,處理循環Thread write_Stream= new Thread(new Runnable() {@Overridepublic void run() {//循環輸入數據Scanner scanner=new Scanner(System.in);while ("1".equals("1")){String send_msg=scanner.nextLine()+"--[Client]";writer.println(send_msg);writer.flush();}}});write_Stream.start();while ("1".equals("1")) {//獲取輸入流,得服務端的數據reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));String line=null;while ((line=reader.readLine())!=null){System.out.println(line);}}writer.close();} catch (IOException e) {//鏈接失敗 文件讀取失敗 e.printStackTrace();}finally {//關閉流try {reader.close();socket.shutdownInput();socket.shutdownOutput();} catch (IOException e) {e.printStackTrace();}}} }

轉載于:https://www.cnblogs.com/ljp-sun/p/6576720.html

總結

以上是生活随笔為你收集整理的在Java中使用Socket模拟客户端和服务端(多线程)的全部內容,希望文章能夠幫你解決所遇到的問題。

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