最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java編程Socket實(shí)現(xiàn)多個(gè)客戶端連接同一個(gè)服務(wù)端代碼

 更新時(shí)間:2017年11月22日 14:30:36   作者:大智若愚的小懂  
這篇文章主要介紹了Java編程Socket實(shí)現(xiàn)多個(gè)客戶端連接同一個(gè)服務(wù)端代碼,具有一定參考價(jià)值,需要的朋友可以了解下。

Java Socket(套接字)通常也稱作"套接字",用于描述IP地址和端口,是一個(gè)通信鏈的句柄。應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。

使用Socket實(shí)現(xiàn)多個(gè)客戶端和同一客戶端通訊;首先客戶端連接服務(wù)端發(fā)送一條消息,服務(wù)端接收到消息后進(jìn)行處理,完成后再回復(fù)客戶端一條消息。本人通過自己的思維編寫了一份服務(wù)端和客戶端實(shí)現(xiàn)的代碼,望能與大家相互學(xué)習(xí),共同進(jìn)步。

服務(wù)端代碼

/**
 * Socket服務(wù)端
 * 功能說明:
 * 
 */
public class Server {
	/**
   * 入口
   * 
   * @param args
   * @throws IOException
   */
	public static void main(String[] args) throws IOException {
		// 為了簡單起見,所有的異常信息都往外拋
		int port = 8899;
		// 定義一個(gè)ServiceSocket監(jiān)聽在端口8899上
		ServerSocket server = new ServerSocket(port);
		System.out.println("等待與客戶端建立連接...");
		while (true) {
			// server嘗試接收其他Socket的連接請求,server的accept方法是阻塞式的
			Socket socket = server.accept();
			/**
       * 我們的服務(wù)端處理客戶端的連接請求是同步進(jìn)行的, 每次接收到來自客戶端的連接請求后,
       * 都要先跟當(dāng)前的客戶端通信完之后才能再處理下一個(gè)連接請求。 這在并發(fā)比較多的情況下會(huì)嚴(yán)重影響程序的性能,
       * 為此,我們可以把它改為如下這種異步處理與客戶端通信的方式
       */
			// 每接收到一個(gè)Socket就建立一個(gè)新的線程來處理它
			new Thread(new Task(socket)).start();
		}
		// server.close();
	}
	/**
   * 處理Socket請求的線程類
   */
	static class Task implements Runnable {
		private Socket socket;
		/**
     * 構(gòu)造函數(shù)
     */
		public Task(Socket socket) {
			this.socket = socket;
		}
		@Override
		    public void run() {
			try {
				handlerSocket();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		/**
     * 跟客戶端Socket進(jìn)行通信
     * 
     * @throws IOException
     */
		private void handlerSocket() throws Exception {
			// 跟客戶端建立好連接之后,我們就可以獲取socket的InputStream,并從中讀取客戶端發(fā)過來的信息了
			/**
       * 在從Socket的InputStream中接收數(shù)據(jù)時(shí),像上面那樣一點(diǎn)點(diǎn)的讀就太復(fù)雜了,
       * 有時(shí)候我們就會(huì)換成使用BufferedReader來一次讀一行
       * 
       * BufferedReader的readLine方法是一次讀一行的,這個(gè)方法是阻塞的,直到它讀到了一行數(shù)據(jù)為止程序才會(huì)繼續(xù)往下執(zhí)行,
       * 那么readLine什么時(shí)候才會(huì)讀到一行呢?直到程序遇到了換行符或者是對(duì)應(yīng)流的結(jié)束符readLine方法才會(huì)認(rèn)為讀到了一行,
       * 才會(huì)結(jié)束其阻塞,讓程序繼續(xù)往下執(zhí)行。
       * 所以我們在使用BufferedReader的readLine讀取數(shù)據(jù)的時(shí)候一定要記得在對(duì)應(yīng)的輸出流里面一定要寫入換行符(
       * 流結(jié)束之后會(huì)自動(dòng)標(biāo)記為結(jié)束,readLine可以識(shí)別),寫入換行符之后一定記得如果輸出流不是馬上關(guān)閉的情況下記得flush一下,
       * 這樣數(shù)據(jù)才會(huì)真正的從緩沖區(qū)里面寫入。
       */
			BufferedReader br = new BufferedReader(
			          new InputStreamReader(socket.getInputStream(), "UTF-8"));
			StringBuilder sb = new StringBuilder();
			String temp;
			int index;
			while ((temp = br.readLine()) != null) {
				if ((index = temp.indexOf("eof")) != -1) {
					// 遇到eof時(shí)就結(jié)束接收
					sb.append(temp.substring(0, index));
					break;
				}
				sb.append(temp);
			}
			System.out.println("Form Cliect[port:" + socket.getPort()
			          + "] 消息內(nèi)容:" + sb.toString());
			// 回應(yīng)一下客戶端
			Writer writer = new OutputStreamWriter(socket.getOutputStream(),
			          "UTF-8");
			writer.write(String.format("Hi,%d.天朗氣清,惠風(fēng)和暢!", socket.getPort()));
			writer.flush();
			writer.close();
			System.out.println(
			          "To Cliect[port:" + socket.getPort() + "] 回復(fù)客戶端的消息發(fā)送成功");
			br.close();
			socket.close();
		}
	}
}

客戶端代碼

import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
/** * Socket客戶端
* 功能說明: * * @author 大智若愚的小懂 * @Date 2016年8月30日 * @version 1.0 */
public class Client {
	/** * 入口 * @param args */
	public static void main(String[] args) {
		// 開啟三個(gè)客戶端,一個(gè)線程代表一個(gè)客戶端 
		for (int i = 0; i < 3; i++) {
			new Thread(new Runnable() {
				@Override public void run() {
					try {
						TestClient client = TestClientFactory.createClient();
						client.send(String.format("Hello,Server!I'm %d.這周末天氣如何。", client.client.getLocalPort()));
						client.receive();
					}
					catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			).start();
		}
	}
	/** * 生產(chǎn)測試客戶端的工廠 */
	static class TestClientFactory {
		public static TestClient createClient() throws Exception {
			return new TestClient("127.0.0.1", 8899);
		}
	}
	/** * 測試客戶端 */
	static class TestClient {
		/** * 構(gòu)造函數(shù) * @param host 要連接的服務(wù)端IP地址 * @param port 要連接的服務(wù)端對(duì)應(yīng)的監(jiān)聽端口 * @throws Exception */
		public TestClient(String host, int port) throws Exception {
			// 與服務(wù)端建立連接 
			this.client = new Socket(host, port);
			System.out.println("Cliect[port:" + client.getLocalPort() + "] 與服務(wù)端建立連接...");
		}
		private Socket client;
		private Writer writer;
		/** * 發(fā)送消息 * @param msg * @throws Exception */
		public void send(String msg) throws Exception {
			// 建立連接后就可以往服務(wù)端寫數(shù)據(jù)了 
			if(writer == null) {
				writer = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
			}
			writer.write(msg);
			writer.write("eof\n");
			writer.flush();
			// 寫完后要記得flush 
			System.out.println("Cliect[port:" + client.getLocalPort() + "] 消息發(fā)送成功");
		}
		/** * 接收消息 * @throws Exception */
		public void receive() throws Exception {
			// 寫完以后進(jìn)行讀操作 
			Reader reader = new InputStreamReader(client.getInputStream(), "UTF-8");
			// 設(shè)置接收數(shù)據(jù)超時(shí)間為10秒 
			client.setSoTimeout(10*1000);
			char[] chars = new char[64];
			int len;
			StringBuilder sb = new StringBuilder();
			while ((len = reader.read(chars)) != -1) {
				sb.append(new String(chars, 0, len));
			}
			System.out.println("Cliect[port:" + client.getLocalPort() + "] 消息收到了,內(nèi)容:" + sb.toString());
			reader.close();
			// 關(guān)閉連接 
			writer.close();
			client.close();
		}
	}
}

接下來模擬一下:

1.首先運(yùn)行服務(wù)端

2.接著運(yùn)行客戶端(開三個(gè)客戶端請求)

為了演示有所區(qū)分,服務(wù)端我使用的是Eclipse工具,客戶端使用的是IntelliJ IDEA工具。這時(shí)可以看到客戶端在控制臺(tái)打印出來的消息

一個(gè)Port端口號(hào)代表一個(gè)客戶端,回過來看下服務(wù)端在控制臺(tái)打印出來的消息

總結(jié)

以上就是本文關(guān)于Java編程Socket實(shí)現(xiàn)多個(gè)客戶端連接同一個(gè)服務(wù)端代碼的全部內(nèi)容,希望對(duì)大家有所幫助。有問題可以留言,小編會(huì)及時(shí)回復(fù)大家的。

相關(guān)文章

  • Java17中record替代Lombok部分功能使用場景探究

    Java17中record替代Lombok部分功能使用場景探究

    這篇文章主要介紹了使用Java17中的record替代Lombok的部分功能,本文來為大家小小的總結(jié)下,我們可以在哪些地方,利用record來替換Lombok
    2024-01-01
  • 解決springmvc項(xiàng)目中使用過濾器來解決請求方式為post時(shí)出現(xiàn)亂碼的問題

    解決springmvc項(xiàng)目中使用過濾器來解決請求方式為post時(shí)出現(xiàn)亂碼的問題

    這篇文章主要介紹了springmvc項(xiàng)目中使用過濾器來解決請求方式為post時(shí)出現(xiàn)亂碼的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot之RabbitMQ的使用方法

    SpringBoot之RabbitMQ的使用方法

    這篇文章主要介紹了SpringBoot之RabbitMQ的使用方法,詳細(xì)的介紹了2種模式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • 深入理解JAVA多線程之線程間的通信方式

    深入理解JAVA多線程之線程間的通信方式

    下面小編就為大家?guī)硪黄钊肜斫釰AVA多線程之線程間的通信方式。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • Java實(shí)現(xiàn)的簡單音樂播放器功能示例

    Java實(shí)現(xiàn)的簡單音樂播放器功能示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的簡單音樂播放器功能,涉及java針對(duì)多媒體文件相關(guān)載入、播放相關(guān)操作技巧,需要的朋友可以參考下
    2019-02-02
  • Java多線程正確使用倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch方法詳解

    Java多線程正確使用倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch方法詳解

    這篇文章主要為大家介紹了Java多線程倒計(jì)時(shí)協(xié)調(diào)器CountDownLatch的正確使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • 如何使用JavaCV進(jìn)行圖像灰度化處理

    如何使用JavaCV進(jìn)行圖像灰度化處理

    在計(jì)算機(jī)視覺和圖像處理領(lǐng)域,圖像灰度化是一項(xiàng)基礎(chǔ)且重要的任務(wù),它將彩色圖像轉(zhuǎn)換為灰度圖像,JavaCV 是一個(gè)強(qiáng)大的開源庫,它提供了對(duì)各種計(jì)算機(jī)視覺算法和圖像處理操作的支持,本文將詳細(xì)介紹如何使用 JavaCV 進(jìn)行圖像灰度化處理,需要的朋友可以參考下
    2024-10-10
  • 將項(xiàng)目上傳到Maven中央倉庫(2023最新版)

    將項(xiàng)目上傳到Maven中央倉庫(2023最新版)

    本文主要介紹了將項(xiàng)目上傳到Maven中央倉庫(2023最新版),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 詳解Spring配置文件中bean的相關(guān)屬性

    詳解Spring配置文件中bean的相關(guān)屬性

    這篇文章主要為大家詳細(xì)介紹了Spring配置文件中bean的相關(guān)屬性的知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • SpringBoot?熱搜與不雅文字過濾的實(shí)現(xiàn)

    SpringBoot?熱搜與不雅文字過濾的實(shí)現(xiàn)

    本文主要介紹了SpringBoot?熱搜與不雅文字過濾的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論

邹平县| 财经| 宝坻区| 兴安盟| 大港区| 黄陵县| 河西区| 江北区| 嘉禾县| 夏邑县| 阿合奇县| 遂宁市| 特克斯县| 区。| 康保县| 福清市| 义马市| 敖汉旗| 永胜县| 卢氏县| 礼泉县| 泌阳县| 巴塘县| 察雅县| 德格县| 宝清县| 板桥市| 万全县| 绵竹市| 南汇区| 丹阳市| 仁布县| 洪泽县| 新郑市| 平武县| 郯城县| 宝鸡市| 河北省| 西平县| 屏东县| 印江|