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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

linux网络IO

發(fā)布時(shí)間:2024/9/30 linux 99 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux网络IO 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Socket

服務(wù)端代碼

package io.unittest;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException;/*** Author: ljf* CreatedAt: 2021/3/28 上午10:05*/ public class SocketIOProperties {private static final int RECEIVE_BUFFER = 10;private static final int SO_TIMEOUT = 0;private static final boolean REUSE_ADDR = false;private static final int BACK_LOG = 2; // 連接的等待隊(duì)列滿了之后還能拍幾個(gè),linux一切皆文件嘛,意味著等著不分配文件描述符的有兩個(gè)private static final boolean CLI_KEEPALIVE = false;private static final boolean CLI_OOB = false;private static final int CLi_REC_BUF = 20;private static final boolean CLI_REUSE_ADDR = false;private static final int CLI_SEND_BUF = 20;private static final boolean CLI_LINGER = true; // 服務(wù)關(guān)閉后端口是否立即釋放private static final int CLI_LINGER_N = 0;private static final int CLI_TIMEOUT = 0;private static final boolean CLI_NO_DELAY = false;public static void main(String[] args) {ServerSocket server = null;try {server = new ServerSocket();server.bind(new InetSocketAddress(9090), BACK_LOG);server.setReceiveBufferSize(RECEIVE_BUFFER);server.setReuseAddress(REUSE_ADDR);server.setSoTimeout(SO_TIMEOUT);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}System.out.println("server up use 9090 !");jibeitry {while (true) {System.in.read(); // 這里阻塞住,看沒(méi)有客戶端的情況下,server端怎么處理連接Socket client = server.accept();System.out.println("client port: " + client.getPort());client.setKeepAlive(CLI_KEEPALIVE);client.setOOBInline(CLI_OOB);client.setReceiveBufferSize(CLi_REC_BUF);client.setReuseAddress(CLI_REUSE_ADDR);client.setSendBufferSize(CLI_SEND_BUF);client.setSoLinger(CLI_LINGER, CLI_LINGER_N);client.setSoTimeout(CLI_TIMEOUT);client.setTcpNoDelay(CLI_NO_DELAY);jibei// client.read //阻塞 沒(méi)有 -1 0new Thread(() -> {try {InputStream in = client.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));char[] data = new char[1024];while (true) {int num = reader.read();if (num > 0) {System.out.println("client read some data is : " + num + " val :" + new String(data, 0, num));} else if (num == 0) {System.out.println("client readed nothing!");continue;} else {System.out.println("client readed -1 ..."); // 客戶端斷開,就是-1System.in.read();break;}}} catch (IOException e) {e.printStackTrace();}}).start();}} catch (IOException e) {e.printStackTrace();} finally {try {server.close();} catch (IOException e) {e.printStackTrace();}}} }

客戶端代碼

package io.unittest;import java.io.*; import java.net.Socket;/*** Author: ljf* CreatedAt: 2021/3/28 上午11:07*/ public class SocketClient {public static void main(String[] args) throws IOException {Socket client = new Socket("192.168.150.11", 9080);client.setSendBufferSize(20);client.setTcpNoDelay(true);OutputStream out = client.getOutputStream();InputStream in = System.in;BufferedReader reader = new BufferedReader(new InputStreamReader(in));while (true) {String line = reader.readLine();if (line != null) {byte[] bb = line.getBytes();for (byte b : bb) {out.write(b);}}}} }

開兩臺(tái)虛擬機(jī),總共開4個(gè)控制臺(tái)界面,一臺(tái)(1號(hào))服務(wù)器運(yùn)行界面,一臺(tái)(2號(hào))客戶端運(yùn)行界面,一臺(tái)監(jiān)控(3號(hào)) netstat -natp 查看端口和連接情況,一臺(tái) (4號(hào))tcpdump -nn -i ens33 port 9090 監(jiān)控tcp連接情況,操作步驟:
1.4號(hào)運(yùn)行 tcpdump -nn -i ens33 port 9090 ,啥也沒(méi)有

2.1號(hào)運(yùn)行 java io.unittest.SocketIOProperties,服務(wù)開啟,因?yàn)橛蠸ystem.in.read()阻塞住了,所以沒(méi)有取接收客戶端

3.3號(hào) netstat -natp ,發(fā)現(xiàn)服務(wù)端在監(jiān)控9090端口 ,這時(shí)候4號(hào)的抓包沒(méi)有任何反應(yīng),說(shuō)明沒(méi)有建立連接

lsof -p 2960,發(fā)現(xiàn)內(nèi)核已經(jīng)分配資源,文件描述符6,在監(jiān)聽狀態(tài)

4.2號(hào)客戶端 java io.unittest.SocketClient,沒(méi)有報(bào)錯(cuò),說(shuō)明客戶端啟動(dòng)ok

6.看抓包的4號(hào)機(jī)器,有了客戶端與服務(wù)端的3次tcp握手

7.3號(hào)機(jī) netstat -natp ,發(fā)現(xiàn)已經(jīng)建立了連接,但是沒(méi)有進(jìn)程產(chǎn)生,因?yàn)榉?wù)端還在阻塞呢

8.2號(hào)客戶端輸入 1111,回車,

3號(hào)機(jī)看 netstat -natp,發(fā)現(xiàn)服務(wù)端已經(jīng)接收到4個(gè)字節(jié)了,雖然沒(méi)有應(yīng)用程序接受,說(shuō)明在網(wǎng)絡(luò)連接層已經(jīng)完成通信了

且抓包也抓到了正常通信的網(wǎng)絡(luò)狀態(tài),即 tcp 是面向連接的,走完三次握手,內(nèi)核就已經(jīng)分配資源(緩沖區(qū)等),雖然應(yīng)用程序沒(méi)有接收,但是tcp連接照樣開啟了,占用系統(tǒng)資源了。
9.1號(hào)機(jī)回車,跳過(guò)阻塞,發(fā)現(xiàn)接收到了客戶端的數(shù)據(jù)

這時(shí)候 netstat -natp ,發(fā)現(xiàn)連接已經(jīng)分配給2960進(jìn)程了

且文件描述符也得到了,即7u

總結(jié)

1.tcp是面向連接的,可靠的傳輸協(xié)議,三次握手之后,雙方內(nèi)核就開啟資源,即代表就有了連接。
2.socket是4元組,內(nèi)核級(jí)的,服務(wù)端IP+服務(wù)端端口+客戶端IP+客戶端端口,即這4個(gè)元只要有一元不相同,即能辨識(shí)出來(lái)是唯一的資源,就能建立連接。意味著服務(wù)器雖然默認(rèn)最多開啟65535個(gè)端口,但是一個(gè)端口可以listen多個(gè)socket,只要內(nèi)存夠分配文件描述符,理論上連接可以是端口號(hào)數(shù)量的幾倍。

參數(shù) BACK_LOG

表示最多有幾個(gè)不接收的連接在隊(duì)列里等待,操作步驟:
1.服務(wù)端開啟,阻塞住;
2.客戶端瘋狂連接

設(shè)置back_log是2,服務(wù)端接收到第4個(gè)連接的時(shí)候狀態(tài)就是 SYN_RECV了,可以理解為服務(wù)端不處理這個(gè)連接了。這個(gè)參數(shù)可以用來(lái)控制負(fù)載均衡的服務(wù)器訪問(wèn)量,netty尤為有用

參數(shù) SO_TIMEOUT

1.server在listen狀態(tài)的超時(shí)時(shí)長(zhǎng),超過(guò)這個(gè)時(shí)間沒(méi)有連接進(jìn)來(lái),就拋異常,打斷這次等待,重新等待新的連接。
2.連進(jìn)來(lái)的客戶端,即server.accept()過(guò)來(lái)的客戶端,這個(gè)參數(shù)表示連接進(jìn)來(lái)了在時(shí)長(zhǎng)內(nèi)沒(méi)有收到數(shù)據(jù)包,就斷開這個(gè)連接,防止客戶端一直在消耗資源。比如你連接百度,但是就一直不發(fā)請(qǐng)求頭,過(guò)一會(huì)再發(fā)就連接失效了。

參數(shù)NODELAY

tcp連接有發(fā)包的優(yōu)化策略,如果包太小了就攢在一起大點(diǎn)了再發(fā),可以通過(guò)setNoDelay(true),讓每個(gè)包無(wú)論大小都發(fā)。

參數(shù)keepalive

如果建立了連接了,雙方都不通話,那么誰(shuí)都不知道對(duì)方是否還存活,設(shè)置keepalive是true,客戶端會(huì)網(wǎng)服務(wù)端發(fā)確認(rèn)包,服務(wù)端也給客戶端發(fā)確認(rèn)包,保持連接存活。

總結(jié)

以上是生活随笔為你收集整理的linux网络IO的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。