TCP網路程式設計之echo回射程式

2021-08-13 02:12:11 字數 3226 閱讀 2643

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端後建立可靠的 雙向的 持...