TCP客戶 服務端程式示例

2021-07-14 21:10:07 字數 3736 閱讀 7419

書中的例子中,作者自己封裝了很多方法和標頭檔案(本書有原始碼,需要按要求編譯執行)。我做了修改,自己照著敲,可能方法上不太嚴謹,不會應當是可以執行的,自己敲出來也是一種學習。

我們要實現如下的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 ...