今天開始在Linux(Ubuntu)下面學習網絡編程。學習的過程,老是會遇到不少問題,可是解決了,感受很棒。編程
一、下載源代碼,便於參考vim
http://www.ituring.com.cn/book/164?q=unix%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B網絡
隨書代碼socket
二、下載完成後解壓,打開README文檔tcp
QUICK AND DIRTY =============== Execute the following from the src/ directory: ./configure # try to figure out all implementation differences cd lib # build the basic library that all programs need make # use "gmake" everywhere on BSD/OS systems cd ../libfree # continue building the basic library make cd ../libroute # only if your system supports 4.4BSD style routing sockets make # only if your system supports 4.4BSD style routing sockets cd ../libxti # only if your system supports XTI make # only if your system supports XTI cd ../intro # build and test a basic client program make daytimetcpcli ./daytimetcpcli 127.0.0.1 If all that works, you're all set to start compiling individual programs. Notice that all the source code assumes tabs every 4 columns, not 8.
所謂的 src/ directory 指得是解壓得文檔。打開終端函數
cd /home/themo/下載/unpv13e (cd 後面得路徑換成文件解壓後的文件夾路徑)學習
按照要求一次執行命令。若是擔憂打字錯誤,能夠直接拷貝粘貼ui
執行./daytimetcpcli 127.0.0.1 可能會報錯 「connection refused」.這是由於本機的tcp daytime服務沒有啓動。
spa
三、啓動daytime 服務。 參考自:http://blog.csdn.net/qpengyanting123/article/details/17503163.net
sudo apt-get install xinetd
cd /etc/xinetd.d
sudo vim daytime
(操做:)是將此文件中的兩個 disable 的值 yes 改成 no
sudo stop xinetd (註釋:從新啓動xinetd服務)
sudo start xinetd
//注意權限得問題。daytime文件的權限 root "wr",因此須要得到root權限。sudo vim daytime
此時再次運行 ./daytimetcpcli 127.0.0.1 仍然顯示「connection refused」,緣由爲啓動了Ubuntu防火牆,沒有容許13號端口。執行以下代碼
sudo ufw allow 13
cd /home/themo/下載/unpv13e/intro (註釋:替換成unpv13e所在的路徑)
./daytimetcpcli 127.0.0.1
獲得以下結果
23 MAR 2014 10:09:03 CST
服務配置成功!
四、至此環境就已經配置完成。開始編寫第一個程序:1.2一個簡單的時間獲取客戶程序
#include "unp.h" #include "error.c" //注意這是錯誤處理函數的頭文件 int main(int argc,char *argv[]) { int sockfd, n; char recvline[MAXLINE+1]; struct sockaddr_in servaddr; if(argc != 2) err_quit("usage: a.out <IPaddress>"); if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0) err_sys("socket error"); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(13); if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) err_quit("inet_pton error for %s", argv[1]); if(connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) < 0) err_sys("connect error"); while((n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; if(fputs(recvline, stdout) == EOF) err_sys("fputs error"); } if(n < 0) err_sys("read error"); exit(0); }
注意書本上得代碼沒有添加錯誤處理函數的頭文件,必須加上#include "error.c" 不然函數找不到定義。
編寫源文件完成後,咱們要進行編譯的工做。關於Linux環境下C\C++的編譯,推薦一本電子書給你們,總比在網上查閱參差不齊的信息來得靠譜多了。
Google搜索: An Introduction to GCC.pdf
下面咱們簡單說明下Linux下C++的編譯
移動到.cpp源文件所在得目錄
g++ -o 輸出文件名.out 源文件名.cpp (註釋:執行後能夠看到目錄下出現:輸出文件名.out 的文件)
./輸出文件名.out (註釋:執行程序)
本代碼中用到了 #include "unp.h" 和 #include "error.c" 那編譯器須要知道這兩個文件存放在哪裏。這兩個文件存放在咱們第1步下載得源碼文件夾中。對於我得計算機來講是:
/home/themo/下載/unpv13e/lib 替換成你本身的路徑
因此咱們在編譯 「一個簡單的時間獲取客戶程序」 須要告訴編譯器要包含得頭文件所在的文件夾
具體細節參見:An Introduction to GCC.pdf Chapter 3
可用以下代碼編譯:
g++ -o get-time.out -g -Wall -I/home/themo/下載/unpv13e/lib get-time.cpp (註釋:編譯cpp)
./get-time.out 127.0.0.1 (註釋:執行程序)
終端輸出程序執行結果:
themo@themo:~/文檔/network$ ./get-time.out 127.0.0.1 23 MAR 2014 11:55:34 CST
說明:
g++ C++編譯指令
-o get-time.out 指定編譯後得文件get-time.out,若未指定默認獲得 a.out
-I/home/themo/下載/unpv13e/lib -I/包含路徑,指定cpp中#include 「」 的文件要到哪裏找。
-g 添加調試信息,使用gdb調試時起做用
get-time.cpp 源文件名
若有不明白,歡迎提問。