標籤:freebsd 網路編程 daytimetcpcli
最近開始學習unix網路編程,開篇第一個程式daytimetcpcli.c編譯運行成功,就花費了很多心思,把問題匯總出來,供各位參考。
FreeBsd unix 系統構建的vmware虛擬機器,之前對FreeBsd也是小白,雖說也玩過linux,對網路通訊這些設定啊還是不熟。
書中原始碼如下:
#include "../lib/unp.h"
#include "../lib/error.c"
int
main(int argc, char **argv)
{
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_inservaddr;
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);/* daytime server */
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;/* null terminate */
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
exit(0);
}
FreeBsd 安裝成功後,telnet 和ftp這些服務,要自己開啟,在/etc/inetd.conf,用ee命令開啟,可以直接編輯,
要儲存必須用root許可權,esc後aa儲存。ps -ef | grep inetd 查看PID號,kill 後,用 inetd -wW重
新開啟,新設定生效。
編輯其實就是去掉相應行的“#”注釋。
#ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
#ftp stream tcp6 nowait root /usr/libexec/ftpd ftpd -l
#telnet stream tcp nowait root /usr/libexec/telnetd telnetd
#telnet stream tcp6 nowait root /usr/libexec/telnetd telnetd
言歸正傳,cc daytimetcpcli.c,產生a.out, 運行./a.out 127.0.0.1
總是提示connect error: Connection refused。
用sockstat 查看伺服器啟動並執行連接埠,有21,23這些常見的連接埠。
百度說應該沒有開daytime服務連接埠。看freebsd手冊,說這些服務是內建預設啟動的。
再回到網路編程書中,看後面的代碼解釋,知道是connect執行失敗,再分析後關鍵點在
htons(13)這個函數,
其中13是服務連接埠號碼,把13改成其他連接埠看看,然後改成21,發現執行成功。
雖然執行成功,但是不是書中的daytime字串,心裡還是有些遺憾。現在至少能證明
伺服器沒有問題,應該是配置還有些沒有設定正確。繼續百度。
隨後在基維百科中看到daytime協議的解釋:
DAYTIME協議(英語:DAYTIME protocol)是一個在RFC 867內定義的網路傳輸協議。
主機可以用TCP或UDP連接埠 13串連支援DAYTIME協議的伺服器。
伺服器會以ASCII字元傳回當時日期及時間。格式類似:星期,月 日,年 時區。
它也用作測試電腦網路的聯通性,現在測試網路的方法已經轉為用ping或traceroute。
DAYTIME協議在inetd上
在Linux、FreeBSD,或其他類UNIX作業系統中,DAYTIME時間伺服器是在inetd中內建。通常DAYTIME協議服務是預設關閉的,或是在/etc/inetd.conf檔案中加上以下資料以開啟服務:
daytime stream tcp nowait root internaldaytime stream tcp6 nowait root internaldaytime dgram udp wait root internaldaytime dgram udp6 wait root internal
看了上面的解釋,再把daytime服務開啟,重新啟動inetd,一切OK
看到inetd.conf裡面有很多#開頭的行,應該是很多服務都要手工開啟。
書中第一個例子總算完美執行成功,這樣的開始才讓人欣喜。小白繼續前進
<<unix 網路編程>> 源碼編譯daytimetcpcli.c 問題匯總