欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java TCP編程之Scoket

 更新時(shí)間:2022年11月05日 17:22:30   作者:OlaiolaiO  
TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會(huì)保證數(shù)據(jù)不丟包、不亂序。TCP全名是Transmission Control Protocol,它是位于網(wǎng)絡(luò)OSI模型中的第四層

一、什么是Scoket

Socket 是一個(gè)抽象概念,一個(gè)應(yīng)用程序通過(guò)一個(gè) Socket 來(lái)建立一個(gè)遠(yuǎn)程連接,而 Socket 內(nèi)部通 過(guò) TCP/IP 協(xié)議把數(shù)據(jù)傳輸?shù)骄W(wǎng)絡(luò)。

┌───────────┐                                   ┌───────────┐
│Application│                                   │Application│
├───────────┤                                   ├───────────┤
│  Socket   │                                   │  Socket   │
├───────────┤                                   ├───────────┤
│    TCP    │                                   │    TCP    │
├───────────┤      ┌──────┐       ┌──────┐      ├───────────┤
│    IP     │<────>│Router│<─────>│Router│<────>│    IP     │
└───────────┘      └──────┘       └──────┘      └───────────┘

Socket 、 TCP 和部分 IP 的功能都是由操作系統(tǒng)提供的,不同的編程語(yǔ)言只是提供了對(duì)操作系統(tǒng)調(diào) 用的簡(jiǎn)單的封裝。例如, Java 提供的幾個(gè) Socket 相關(guān)的類就封裝了操作系統(tǒng)提供的接口: Server Socket 類、 Socket 類。

為什么需要 Socket 進(jìn)行網(wǎng)絡(luò)通信?因?yàn)閮H僅通過(guò) IP 地址進(jìn)行通信是不夠的,同 一臺(tái)計(jì)算機(jī)同一時(shí)間會(huì)運(yùn)行多個(gè)網(wǎng)絡(luò)應(yīng)用程序,例如瀏覽器、QQ、郵件客戶端等。當(dāng) 操作系統(tǒng)接收到一個(gè)數(shù)據(jù)包的時(shí)候,如果只有 IP 地址,它沒(méi)法判斷應(yīng)該發(fā)給哪個(gè)應(yīng)用 程序,所以,操作系統(tǒng)抽象出 Socket 接口,每個(gè)應(yīng)用程序需要各自對(duì)應(yīng)到不同的 S ocket ,數(shù)據(jù)包才能根據(jù) Socket 正確地發(fā)到對(duì)應(yīng)的應(yīng)用程序。

一個(gè) Socket 就是由IP地址和端口號(hào)(范圍是0~65535)組成,可以把 Socket 簡(jiǎn)單理解為 IP 地址加端口號(hào)。端口號(hào)總是由操作系統(tǒng)分配,它是一個(gè) 0 ~ 65535 之間的數(shù)字,其中,小于 1024 的端口屬于特權(quán)端口,需要管理員權(quán)限,大于 1024 的端口可以由任意用戶的應(yīng)用程序打開(kāi)。

使用 Socket 進(jìn)行網(wǎng)絡(luò)編程時(shí),本質(zhì)上就是兩個(gè)進(jìn)程之間的網(wǎng)絡(luò)通信。其中一個(gè)進(jìn) 程必須充當(dāng)服務(wù)器端,它會(huì)主動(dòng)監(jiān)聽(tīng)某個(gè)指定的端口,另一個(gè)進(jìn)程必須充當(dāng)客戶端,它 必須主動(dòng)連接服務(wù)器的 IP 地址和指定端口,如果連接成功,服務(wù)器端和客戶端就成功 地建立了一個(gè) TCP 連接,雙方后續(xù)就可以隨時(shí)發(fā)送和接收數(shù)據(jù)。

當(dāng) Socket 連接成功地在服務(wù)器端和客戶端之間建立后:

  • 對(duì)服務(wù)器端來(lái)說(shuō),它的 Socket 是指定的 IP 地址和指定的端口號(hào);
  • 對(duì)客戶端來(lái)說(shuō),它的 Socket 是它所在計(jì)算機(jī)的 IP 地址和一個(gè)由操作系統(tǒng)分配的隨機(jī)端口號(hào)。

二、服務(wù)器端

package com.ljl.tcp.demo2;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class ChatServer {
	public static void main(String[] args) {
		Map<String, String> chatMap = new HashMap<String, String>(){
			{
				put("你好", "你好呀");
				put("hi", "hi~");
				put("hello", "哈嘍");
				put("吃了嗎", "沒(méi)呢,你呢");
				put("孤勇者", "愛(ài)你孤身走暗巷");
				put("有請(qǐng)潘周聃", "潘周聃,今年29歲,蘇黎世理工大學(xué).....");
				put("很高興認(rèn)識(shí)你", "我也是哦");
			}
		};
		try (ServerSocket server = new ServerSocket(9966)) {
			while(true) {
			//客戶端連接
			Socket client = server.accept();
			//獲取客戶端IP地址
			String clientIP = client.getInetAddress().getHostAddress();
			try(
			BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));){	
			//獲取客戶端提問(wèn)
			String question = reader.readLine();
			System.out.println("服務(wù)器來(lái)自客戶端"+clientIP+"的提問(wèn):"+question);
			//獲取問(wèn)題答案
			String answer = chatMap.get(question);
			answer = answer == null?"我不知道你在說(shuō)啥":answer;
			//發(fā)送答案至客戶端
			writer.write(answer);
			}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

三、客戶端

package com.ljl.tcp.demo2;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
public class ChatClient {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		while(true) {
		try (//創(chuàng)建Socket
		 Socket client = new Socket("192.168.254.163",9966);
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));	
			BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
			){
			//獲取控制臺(tái)的輸入問(wèn)題
			String question = input.nextLine();
			if(question.equals("退下")) {
				break;
			}
			//發(fā)送問(wèn)題至服務(wù)器
			writer.write(question);
			writer.flush();
			//暫時(shí)結(jié)束本次輸入
			client.shutdownOutput();
			//獲取來(lái)自服務(wù)器的答案
			String answer = reader.readLine();
			System.out.println("服務(wù)器回答:"+answer);
		} catch (IOException e) {
			e.printStackTrace();
		}
		}
		System.out.println("over");
	}
}

四、Socket流

當(dāng) Socket 連接創(chuàng)建成功后,無(wú)論是服務(wù)器端,還是客戶端,我們都使用 Socket 實(shí)例進(jìn)行網(wǎng)絡(luò)通信。因?yàn)?T CP 是一種基于流的協(xié)議,因此, Java 標(biāo)準(zhǔn)庫(kù)使用 InputStream 和 OutputStream 來(lái)封裝 Socket 的數(shù)據(jù)流,這 樣我們使用 Socket 的流,和普通 IO 流類似:

// 用于讀取網(wǎng)絡(luò)數(shù)據(jù):
InputStream in = sock.getInputStream();
// 用于寫入網(wǎng)絡(luò)數(shù)據(jù):
OutputStream out = sock.getOutputStream();

寫入網(wǎng)絡(luò)數(shù)據(jù)時(shí),必須要調(diào)用 flush() 方法。如果不調(diào)用 flush() ,我們很可能會(huì)發(fā)現(xiàn),客戶端和服務(wù)器都 收不到數(shù)據(jù),這并不是 Java 標(biāo)準(zhǔn)庫(kù)的設(shè)計(jì)問(wèn)題,而是我們以流的形式寫入數(shù)據(jù)的時(shí)候,并不是一寫入就立刻發(fā)送 到網(wǎng)絡(luò),而是先寫入內(nèi)存緩沖區(qū),直到緩沖區(qū)滿了以后,才會(huì)一次性真正發(fā)送到網(wǎng)絡(luò),這樣設(shè)計(jì)的目的是為了提高 傳輸效率。如果緩沖區(qū)的數(shù)據(jù)很少,而我們又想強(qiáng)制把這些數(shù)據(jù)發(fā)送到網(wǎng)絡(luò),就必須調(diào)用 flush() 強(qiáng)制把緩沖區(qū)數(shù) 據(jù)發(fā)送出去。

五、總結(jié)

使用Java進(jìn)行TCP編程時(shí),需要使用 Socket 模型:

  • 服務(wù)器端用 ServerSocket 監(jiān)聽(tīng)指定端口;
  • 客戶端使用 Socket(InetAddress, port) 連接服務(wù)器;
  • 服務(wù)器端用 accept() 接收連接并返回 Socket 實(shí)例;
  • 雙方通過(guò) Socket 打開(kāi) InputStream / OutputStream 讀寫數(shù)據(jù);
  • 服務(wù)器端通常使用多線程同時(shí)處理多個(gè)客戶端連接,利用線程池可大幅提升效率;
  • flush() 方法用于強(qiáng)制輸出緩沖區(qū)到網(wǎng)絡(luò)。

到此這篇關(guān)于Java TCP編程之Scoket的文章就介紹到這了,更多相關(guān)Java Scoket內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • servlet Cookie使用方法詳解(六)

    servlet Cookie使用方法詳解(六)

    這篇文章主要為大家詳細(xì)介紹了servlet Cookie的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • java 實(shí)現(xiàn)KMP算法

    java 實(shí)現(xiàn)KMP算法

    這篇文章主要介紹了java 如何實(shí)現(xiàn)KMP算法,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-12-12
  • Java使用GUI實(shí)現(xiàn)貪吃蛇游戲詳解

    Java使用GUI實(shí)現(xiàn)貪吃蛇游戲詳解

    小時(shí)候經(jīng)常在諾基亞上玩的一個(gè)小游戲-貪吃蛇,你還記得嗎?本篇帶你重溫一下把它實(shí)現(xiàn),做的比較簡(jiǎn)單,但還是可以玩的.感興趣的朋友快來(lái)看看吧
    2022-05-05
  • java輸入字符串并將每個(gè)字符輸出的方法

    java輸入字符串并將每個(gè)字符輸出的方法

    今天小編就為大家分享一篇java輸入字符串并將每個(gè)字符輸出的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • MyBatis實(shí)現(xiàn)兩種查詢樹(shù)形數(shù)據(jù)的方法詳解(嵌套結(jié)果集和遞歸查詢)

    MyBatis實(shí)現(xiàn)兩種查詢樹(shù)形數(shù)據(jù)的方法詳解(嵌套結(jié)果集和遞歸查詢)

    樹(shù)形結(jié)構(gòu)數(shù)據(jù)在開(kāi)發(fā)中十分常見(jiàn),比如:菜單數(shù)、組織樹(shù), 利用 MyBatis 提供嵌套查詢功能可以很方便地實(shí)現(xiàn)這個(gè)功能需求。本文主要介紹了兩種方法,感興趣的可以了解一下
    2021-09-09
  • Java實(shí)現(xiàn)Excel表單控件的添加與刪除

    Java實(shí)現(xiàn)Excel表單控件的添加與刪除

    本文通過(guò)Java代碼示例介紹如何在Excel表格中添加表單控件,包括文本框、單選按鈕、復(fù)選框、組合框、微調(diào)按鈕等,以及如何刪除Excel中的指定表單控件,需要的可以參考一下
    2022-05-05
  • Java服務(wù)調(diào)用RestTemplate與HttpClient的使用詳解

    Java服務(wù)調(diào)用RestTemplate與HttpClient的使用詳解

    無(wú)論是微服務(wù)還是SOA,都面臨著服務(wù)間的遠(yuǎn)程調(diào)用,這篇文章主要介紹了服務(wù)調(diào)用RestTemplate與HttpClient的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表詳解

    Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表詳解

    鏈表是一種物理存儲(chǔ)單元上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),java代碼實(shí)現(xiàn)單鏈表,插入,刪除和遍歷等功能,這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)和算法之鏈表的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Java實(shí)現(xiàn)五子棋AI算法

    Java實(shí)現(xiàn)五子棋AI算法

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)五子棋AI算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 深入理解Netty核心類及其作用

    深入理解Netty核心類及其作用

    本文介紹了Netty框架中的核心類及其作用,包括Channel、EventLoop、ChannelPipeline、ByteBuf等,通過(guò)對(duì)這些類的深入理解,可以更好地使用Netty進(jìn)行網(wǎng)絡(luò)編程開(kāi)發(fā)
    2023-04-04

最新評(píng)論