書中的例子中,作者自己封裝了很多方法和標頭檔案(本書有原始碼,需要按要求編譯執行)。我做了修改,自己照著敲,可能方法上不太嚴謹,不會應當是可以執行的,自己敲出來也是一種學習。
我們要實現如下的tcp客戶/伺服器
服務端 server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 9877
#define queue 20
#define buffer_size 1024
/* write n bytes to a descrpiter */
ssize_t write(int fd,const
void *vptr, size_t n)
nleft = -nwritten;
ptr += nwritten;
}return n;
}void str_echo(int sockfd)
int main()
// listen,成功返回0,出錯返回-1
if(listen(server_sockfd,queue) == -1)
while(1)
char buff[buffer_size];
// 顯示連線的客戶端
printf("connection from %s, port %d\n",
inet_ntop(af_inet, &client_addr.sin_addr, buff, sizeof(buff)),
ntohs(client_addr.sin_port));
pid_t child_pid ;
if( (child_pid = fork()) == 0 ) // 為客戶端fork子程序
close(conn);
}return
0;}
客戶端 client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 9877
#define buffer_size 1024
ssize_t readline(int fd, void *vptr, size_t maxlen)
else
if( rc == 0) else
}*ptr = 0;
return n;
}void str_cli(file *fp, int sockfd)
}int main()
str_cli(stdin,sock_cli); //回射客戶端的程式
exit(0);
}
執行圖:
我在**中新增了顯示連線的客戶端的資訊。
關於write readline函式也是書中的
知識點:
1 write readline函式封裝?
當不使用封裝的函式write,readline函式,而直接使用 read,write時,程式執行的結果如上圖所示。有亂碼
位元組流套接字字上呼叫read和write輸入或輸出的位元組數可能比請求的數量少,多的現象。這是因為在核心中用於套接字的緩衝區可能已經到達了極限,會出現不足乙個位元組的計數值,這樣就需要自己重新編寫,實現乙個乙個位元組的讀取和寫入。(作者說明了原因,也封裝了上面的方法)。
2 tcp 連線終止(四次握手) 出現了 time_wait狀態
3 出現了殭屍程序
子程序結束後,父程序並沒有對子程序進行任何處理(呼叫wait來收集殭屍程序),顯然會存在殭屍程序。
各種問題及原因,要自己閱讀圖書並實踐。。。
訊號處理,解決殭屍程序,wait / waitpid
server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 9877
#define queue 20
#define buffer_size 1024
void sig_child(int signo)
/* write n bytes to a descrpiter */
ssize_t write(int fd,const
void *vptr, size_t n)
nleft = -nwritten;
ptr += nwritten;
}return n;
}void str_echo(int sockfd)
int main()
// listen,成功返回0,出錯返回-1
if(listen(server_sockfd,queue) == -1)
signal(sigchld, sig_child);// 訊號處理
while(1)
char buff[buffer_size];
// 顯示連線的客戶端
printf("connection from %s, port %d\n",
inet_ntop(af_inet, &client_addr.sin_addr, buff, sizeof(buff)),
ntohs(client_addr.sin_port));
pid_t child_pid ;
if( (child_pid = fork()) == 0 ) // 為客戶端fork子程序
利用waitpid
void sig_child(int signo)
wait waitpid 的區別和作用可以參考圖書講解 或 博文:
tcp 三次握手和四次揮手,參考學習如下博文
TCP客戶端服務端demo
服務端程式 include include include include include include include int main 列印握手成功的客戶端 struct sockaddr in servaddr socklen t nservlen sizeof servaddr getso...
php編寫TCP服務端和客戶端程式
1 修改php.ini,開啟extension php sockets.dll 2 服務端程式socketserver.php 確保在連線客戶端時不會超時 set time limit 0 設定ip和埠號 address 127.0.0.1 port 3046 建立乙個socket af inet ...
php編寫TCP服務端和客戶端程式
1 修改php.ini,開啟extension php sockets.dll 2 服務端程式socketserver.php 確保在連線客戶端時不會超時 set time limit 0 設定ip和埠號 address 127.0.0.1 port 3046 建立乙個socket af inet ...