tcp網路程式設計有三個例子最值得學習研究,分別是echo、chat、proxy,都是長連線協議。接下來,把這幾個例子都實現。本節用乙個簡單的例子來講tcp客戶/伺服器程式框架,這也是echo的實現。
程式的基本流程:
客戶從標準輸入鍵入一行文字,並傳送給伺服器。
伺服器接收到文字之後回射給客戶端。
客戶端接收到伺服器的文字,把它顯示到標準輸出上。
儘管下列實現**很簡單,但是它已經闡述了基本的tcp客戶/伺服器的框架,想要實現任何複雜的程式都可以以這個程式作為基本框架來開發。比如做成一問一答的方式,收到的請求和傳送響應的內容不一樣,這時候要考慮打包與拆包格式的設計,進一步還可以寫簡單的http服務。以下貼出原始碼。後續以tcp socket的框架寫個簡單功能的聊天室。
//server_echo.c
#include
#include
#include
#include
#include
#include
#include
#include
#define serv_port 9877
#define listenq 1024
#define maxline 4096
void str_echo(int sockfd)
printf("server send\n");
if (send(sockfd,buff,maxline,0) < 0)
bzero(buff, sizeof(buff));
}}int main(int argc, char **argv)
printf("create socket success!\n");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_addr.s_addr = htonl(inaddr_any);
servaddr.sin_port = htons(serv_port);
// 設定套接字選項避免位址使用錯誤,為了允許位址重用,我設定整型引數(on)為 1 (不然,可以設為 0 來禁止位址重用)
int on=1;
if((setsockopt(listenfd,sol_socket,so_reuseaddr,&on,sizeof(on)))<0)
if(bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
printf("bind success!\n");
if(listen(listenfd, listenq) == -1)
for ( ; ; )
printf("begin fork!\n");
fpid=fork();
if (fpid < 0)
else
if (fpid == 0) //child process
close(connfd); // parent closes connected socket
}}
//client_echo.c
#include
#include
#include
#include
#include
#include
#include
#include
#define maxline 4096
#define serv_port 9877
void str_cli(file *fp, int sockfd)
if (recv(sockfd,recvline,maxline,0) < 0 )
printf("recvline : %s\n",recvline);
fputs(recvline, stdout);
}}int main(int argc, char **argv)
sockfd = socket(af_inet, sock_stream, 0);
if (sockfd < 0)
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_port = htons(serv_port);
if (inet_pton(af_inet, argv[1], &servaddr.sin_addr) < 0)
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
str_cli(stdin, sockfd);
exit(0);
}
測試結果如下:
ubuntu:~/test/
1214-test$ ./server_echo
create socket success!
bind success!
begin accept!
begin fork!
begin accept!
server begin recv
server send
ubuntu:~/test/
1214-test$ ./client_echo 192.168.65.1
helloworld
sendline : helloworld
recvline : helloworld
helloworld
在除錯程式的時候,我發現如果伺服器被斷開了,再重新啟動,會出現如下錯誤:
bind: address already in use
查了之後,才知道這是由於套接字處於time_wait狀態引起的,這個時間是幾分鐘,過後再重新啟動伺服器就沒問題了。有時候,我們在除錯程式的時候,為了允許位址重用,可以在bind前加上這兩句話可以避免這種狀況,設定整型引數 on 為 1 (不然,可以設為 0 來禁止位址重用)。
=1;
if((setsockopt(listenfd,sol_socket,so_reuseaddr,&on
,sizeof(on
)))<0)
TCP 回射程式
客戶端從標準輸入讀入一行文字,並發給伺服器 伺服器從網路輸入讀入這行文字,並且回射給客戶 客戶從網路輸入讀入這行回射文字,並且顯示在標準輸出上。伺服器從網路讀入和返回 void str echo int sockfd while 1 int main 父程序中關閉已連線套接字 close connf...
(unix網路程式設計)tcp回射程式二 避免殭屍程序
本例在上一例的基礎上增加了singal函式來捕捉子程序退出時候產生的sigchld訊號,從而防止子程序變成殭屍程序。伺服器端的 如下 include include include include include include include include include include def...
網路程式設計之TCP程式設計
tcp程式設計中,如果要完成通訊,通訊雙方必須要建立socket,通過socket完成通訊。tcp通訊步驟 1 伺服器啟動serversocket作為通訊的server端,等待客戶端鏈入。2 客戶端建立socket作為通訊的client端 3 client端鏈入server端後建立可靠的 雙向的 持...