FROM Linux公社 http://linux.linuxidc.com
因爲了解WIFI安全,看到BT5,從而接觸到Linux公式。非常感謝Linux公社的公共資源,這真是一個知識的寶庫。
常在linux下進行嵌入式開發,出了校門真正應用還未系統的學習。借項目間隙,學習一下,望能溫故而知心。
第一章 基礎知識
源程序編譯:使用gcc編譯器,主要了解 -o -c -g選項,可以在terminal 輸入man gcc查看原文檔。
Makefile的編寫: 這是一個工程的組織架構,當gcc的東西多了,需要庫和鏈接時就需要這麼一個配置文件進行組織。可以查《和我一起寫Makefile》系統學習。
程序庫的鏈接:gcc 缺省會鏈接常用的庫(/lib / usr/lib /usr/local/lib);需要特定庫時可以使用-L/home/hoyt/mylib 進行鏈接;關於動態庫和靜態庫需要專門查找學習。
程序的調試: 可以使用gdb工具(gcc編譯添加 -g選項),也可以程序中打印變量或輸出日誌文件的方式。各取所好,方便自己就好。
頭文件和系統求助: 找不到時,可以使用man找到具體的用法和所在頭文件。 man write 是write命令的說明; man 2 write是系統調用函數; man 3 write 是C的庫函數。
第二章 進程介紹
進程的概念 :進程是系統執行程序而產生的,系統會分配個ID給它。因爲系統的多用戶並行執行從而有了進程的新建、運行、阻塞、就緒和完成五個狀態。具體參照《操作系統》。
進程的身份: 用戶執行程序,程序分出若干子孫進程,進程需要一定資源。 可以通過getpid();getppid();getuid();geteuid();getgid();getegid()得到進程ID;父進程ID;用戶ID;有效用戶ID;組ID;有效組ID等。
進程的創建: fork();函數可以克隆出一個進程,這個子進程只有ID與自己不同。如果父進程希望阻塞等待可以調用wait();waitpid(); 子進程若調用系統程序可以使用.exec族的5個函數。具體參考 man execl。
守護進程的創建 :守護進程(Daemon)是一種運行在後臺的特殊進程,它獨立於控制終端並且週期性的執行某種任務或等待處理某些發生的事件。對於後臺執行,我麼可以在命令後加&,Shell會將程序放到後臺運行。而對於編碼,可以由父進程創建子進程後,子進程將父進程殺死。子進程就可以定時後臺執行了。
第三章 文件操作
文件的創建和讀寫:文件的創建、打開、讀取、寫入、關閉等動作:fd=open(path,flag,mode);close(fd);read(fd...);write(fd...);
文件的各個屬性:判斷文件是否可以進行某些操作---access(); 若果需要其它的屬性---stat:未打開的文件; fstat:打開的文件。
目錄文件的操作:獲得當前目錄getcwd(buf,size); 還可以創建、打開、讀取、重讀、關閉目錄等動作。
管道文件:linux提供了許多過濾和重定向程序,比如cat more 。還提供了》《><|等重定向操作符。都會用到管道文件。系統調用pipe()可以創建一個管道,也是個緩衝區。重定向fd可以使用dup2();
第四章 時間概念
時間的表示: time():返回1970.1.1開始以來的秒數;ctime():將秒數返回成26長度的字符串時間。
時間的測量:比如要測量程序執行的時間:可以使用gettimeofday()獲取兩次求差。
計時器的使用:Linux操作系統爲每個進程提供了3個內部間隔計時器: ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
第五章 信號處理
信號的產生:一個來源是硬件(如鍵盤按下);另一個是軟件(系統函數或命令),最常用的4個發出信號的系統函數:kill 、 raise 、alarm 、 setitimer。
信號的處理:操作有:信號集合清空、填滿;將信號從集合刪除、添加進去;判斷是否在集合中;將信號集合加入到進程的信號阻塞集合中。阻塞的信號處理與反饋sigaction()。
其他信號函數:pause();掛起直到信號到來。還有一些: sigsuspend();sigsetjmp();siglongjmp();
一個實例:不贅述。
第六章 消息管理(進程通信IPC)
POSIX無名信號量:信號量的使用主要是用來保護共享資源臨界資源,使得資源在一個時刻只有一個進程所擁有。操作函數有sem_init();destroy();wait();trywait();post();getvalue(); -lrt librt.so庫。
System V信號量:ftok();semget();semctl();semop();sembuf{};
System V消息隊列:對消息隊列的操作。msgget();msgsnd();msgrcv();msgctl();
System V共享內存:shmget();shmat()-connect;shmdt()-disconnect;shmctl();
進程通信(IPC)是網絡程序的基礎,在很多的網絡程序當中會大量的使用進程通信的概念和知識。其實進程通信是一件非常複雜的事情,學習它最好的辦法是不對的寫程序和看聯機手冊。
第七章 線程操作
我們編寫的程序大多數可以看成是單線程的,就是程序是按一定的順序來執行。如果我們使用線程的話,程序就會在我們創建線程的地方分叉,編程兩個程序在執行。粗略的看來好像和子進程差不多的,其實不然。子進程是通過拷貝父進程的地址空間來執行的,而線程是通過共享程序代碼來執行的。通俗一點就是線程的相同的代碼會被執行幾次,使用線程的好處是可以節省資源,由於線程是通過共享代碼的,所以沒有進程調度那麼複雜。
線程創建和基本的使用:pthread(); *(*start_routine)(); pthread_exit();pthread_jion(); gcc need lib :-lpthread 例子有些小問題。
線程屬性:不詳
線程互斥:不詳
線程同步;不詳
第八章 網絡編程
1、Linux網絡知識介紹
網絡程序和普通程序區別是由兩個部分組成:客戶端和服務器。先有服務器建立起來,客戶端再去連接對應端口。
常用命令:netstat-顯示網絡連接、路由表、接口統計等網絡信息,常用選項-an。telnet-查看服務器端telnet localhost 8888。
基於TCP/IP協議兩種形式通信: TCP 、 UDP。
2、初等網絡函數介紹
socket編程具有設備無關性。
socket() -- 創建fd。AF_UNIX針對UNIX系統進程間通信,AF_INET針對網絡間通信;SOCK_STREAM是TCP協議,SOCK_DGRAM是UDP協議。
bind() -- 綁定fd和本地端口。struct sockaddr{...} 在linux/socket.h中,爲了系統兼容,我們使用linux/in.h的 struct sockaddr_in{...}。
listen() -- 將bind的fd變爲監聽套接字。
accept() -- 服務器端接收一個連接。
connect() -- 客戶端用來連接服務器。
服務器端: socket --> bind --> listen --> accept
客戶端 : socket -->connect
3、服務器和客戶端的信息函數
字節轉換函數: htonl htons ntohl ntohs h: host n: net s:short l: long
IP和域名的轉換 : gethostbyname() gethostbyaddr() 需要理解netdb.h中 struct hostent結構體。 h_strerror()可以得到出錯信息。
字符串IP 和 32位hexIP 轉換 :inet_aton() inet_ntoa() a: ascii n:network
服務信息函數:getsockname(); getpeername(); getservbyname(); getservbyport(); 較少使用。
4、完整的讀寫函數
write() -- 返回值>0,表示寫入了部分或全部數據; 返回值<0,表示錯誤,可以通過errno得知。
read() -- >0,表示實際讀取字數;=0,表示文件讀取結束;<0,表示錯誤。如果爲EINTR表示中斷導致。
5、用戶數據報發送
針對UDP協議數據通信:
recvfrom(); sendto();
6、高級套接字函數
recv(); send() 的前三個parameters和 read() write()一樣,可是增加了第四個參數 來控制讀寫操作。
recvfrom(); sendto() UDP協議使用。
recvmsg(); sendmsg(); 可以實現以上四個函數的所有功能。
close();shudown(); close(fd)時和我們關閉文件一樣。 shutdown()可以定製關閉讀或者寫通道。
7、TCP/IP協議
分層的網絡協議。從上到下:應用層(app)、表示層(ssl)、會話層(socket)、傳輸層(TCP/UDP)、網絡層(IP ICMP)、數據鏈路層和物理層(802.3 802.11);
根據實際主要了解802.11 IP ICMP TCP UDP SSL。。。
8、套接字選項
sometimes 我們需要控制套接字的行爲,需要函數: getsockopt(); setsockopt();
可以控制通用套接字、IP選項、TCP選項三種。 SOL_SOCKET IPPROTO_IP IPPROTO_TCP。
ioctl可以控制所有的文件描述符的情況。 man ioctl_list。
9、服務器模型
循環服務器:循環服務器在同一時刻只響應一個客戶端的請求。 UDP服務器從套接字上讀取請求,處理後返回給客戶端;TCP服務器接受一個客戶端連接,處理後斷開連接。
併發服務器:併發服務器在同一時刻可響應多個客戶端的請求。 TCP服務器,每個客戶機的請求並不由服務器直接處理,而是服務器創建fork()一個子進程(太耗資源)來處理。多路I/O複用,即select形式(耗時)使用。 UDP併發服務器,fork子進程處理,除非服務器在處理用戶數據時用時較長,否則很少用這個模型。
10、原始套接字
區別於 SOCK_STREAM和SOCK_DGRAM, 還有原始套接字SOCK_RAW。 這個是root權限纔可以創建的套接字。 可以使用原始套接字實現DOS小程序。沒看明白最後例子中爲什麼使用sendto....
第九章 Linux下C開發工具介紹
GNU C編譯器: gcc
使用GCC : gcc [options] [filenames]
GCC選項 : 有100多個 。 常用 -o -llib -g -pg(產生剖析信息及耗時情況等)等,可以 man gcc。
優化選項 : 編譯時爲了易於調試,自動情況下是沒有經過優化的,如果需要優化可以使用-O -O2選項。 gcc 可以同時使用 -g -O使我們在最優化的情況下調試,更接近實際。
用gdb調試gcc程序 :gdb <fname> ; gdb -h 可以得到一些選項的簡單說明。
gdb基本命令: 包括: file kill list net step run quit watch printf break make shell等,支持Tab鍵補全和上下鍵翻頁歷史。gdb filename core,查看產生的core dump;
其他工具 : xxgdb是gdb基於 X Windows圖形界面工具。
calls calltree可以輸出源文件裏的函數調用樹圖。
cproto讀入C源程序文件並自動爲每個函數產生原型申明,可以輸出爲頭文件。
indent 自動縮進代碼的工具。
gprof 剖析程序從而知道那個部分在執行時最費時。可以顯調用次數。
暫時時學習到這