一切接文件
文件描述符
在Linux中所有的都是文件,不管是設備還是真實的文件又或者是任何虛擬的東西比如說控制臺,網絡socket等等在Linux里面這些都是文件。我們來實現(xiàn)一個簡單的例子看看。打開你的Linux服務器輸入一下命令:
[root@VM-0-4-centos ~]# echo $$
26656
[root@VM-0-4-centos ~]# lsof -p $$
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 26656 root 0u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 1u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 2u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 255u CHR 136,0 0t0 3 /dev/pts/0
上面使用$$可以得到當前進程的進程號。然后使用lsof -p 進程號輸出當前進程打開了哪些文件描述符??梢钥吹轿耶斍按蜷_的bash客戶端目前只有0,1,2,255這4個文件描述。
現(xiàn)在使用exec創(chuàng)建新的文件描述符,并且把這個文件描述符指向一個txt文件。
[root@VM-0-4-centos fileio]# cat ls.txt
ls.txt
OSFileIO.class
OSFileIO.java
OSFileIOSleep.class
OSFileIOSleep.java
可以看到ls.txt里面的內容。現(xiàn)在使用exec創(chuàng)建一個文件描述符,將文件描述指向ls.txt這樣你操作文件描述符的時候就像在操作文件.
[root@VM-0-4-centos fileio]# exec 4<> ls.txt
[root@VM-0-4-centos fileio]# lsof -p $$
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 26656 root 0u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 1u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 2u CHR 136,0 0t0 3 /dev/pts/0
bash 26656 root 4u REG 253,1 75 1310913 /root/learning_io/fileio/ls.txt
bash 26656 root 255u CHR 136,0 0t0 3 /dev/pts/0
先看exec 4<> ls.txt4就是文件描述符,在Linux里面文件描述符就是一個數(shù)字,并且這個數(shù)據(jù)不能重復。記住文件描述符的上下文是進程。也就是說進程26656可以有一個文件描述4,同樣的進程26657也可以有一個文件描述符4。<>這個是輸入輸出符號,表示后面的文件ls.txt的輸入和輸出和文件描述4關聯(lián)起來。也就是說4號文件描述符就是ls.txt。
第二個命令lsof -p $$列出了當前進程的文件描述符,可以看到多了一條4號文件描述符,并且指向了/root/learning_io/fileio/ls.txt?,F(xiàn)在我們可以操作4號文件描述符,例如將4號文件描述的內容輸出到終端
[root@VM-0-4-centos fileio]# cat <& 4
ls.txt
OSFileIO.class
OSFileIO.java
OSFileIOSleep.class
OSFileIOSleep.java
上面cat是打開文件的命令,然后<& 4將4號文件描述的內容輸入到cat命令,然后cat將4號對應的內容輸出到控制臺
實驗:在Linux終端訪問百度
1.新建一個文件描述符,并且將文件描述符指向一個socket
2.根據(jù)自身的網絡知識,我向這個socket里面發(fā)送標準的http請求的內容
3.根據(jù)網絡知道這個socket會將我的http內容發(fā)送給百度服務器
4.百度服務器接收到請求后將響應內容輸入到這個socket里面。因為我們的文件描述符就是socket所以可以直接操作這個文件描述符將百度的響應輸出到終端
5.從文件描述符中取出百度的響應
# 新建8號文件描述符,并且打開百度的socket連接請求
exec 8<> /dev/tcp/www.baidu.com/80
# 查看當前進程打開的文件描述符
lsof -p $$
bash 27637 root 8u IPv4 165498974 0t0 TCP VM-0-4-centos:55696->180.101.49.12:http (ESTABLISHED)
# 向8號文件描述符里面寫入http請求最小的標準的文件頭
echo -e 'GET / HTTP/1.1\n' >& 8
# 讀取文件描述里面的響應
cat 0<& 8
這節(jié)主要就是將文件描述符,因為后面網絡IO里面有大量的文件描述符。這里能夠明白后面在學習網絡IO的基礎就有了。