国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux socket編程實例:echo服務器程序

2024-08-27 23:57:44
字體:
來源:轉載
供稿:網友

本文編的是echo服務器示例程序,當收到客戶端的數據,服務器把數據不經加工地發送給客戶,采用TCP連接,采用端口8080進行設計,在整個過程中主要涉及socket的通信。

首先建立一個 socket.代碼如下:

int socketfd;

socketfd = socket(AF_INET, SOCK_STREAM, 0);

socket函數是我們寫socket程序遇到的第一個函數,它在指定的協議上創建一個socket,它的函數說明如下所示:

#include

int socket ( int AddressFamily, int Type, int Protocol)

其中:AddressFamily參數指定socket操作中所要解釋的網絡地址類型,值為如下之一:

AF_UNIX

表示操作系統文件路徑

AF_INET

表示Internet網絡地址

AF_NS

表示XEROX網絡地址

Type參數表明了通信的語義,即通信連接的方式。參數為如下之一:

SOCK_STREAM

提供穩定可靠的連接,并且是雙向的通信方式,如TCP。

SOCK_DGRAM

提供無連接的數據報通信,如UDP。

SOCK_RAW

提供該問內部網絡協議和網絡接口,只有root用戶才可以使用些協議。

返回值:成功則返socket描述符,出錯則返回-1,可通過errno代碼進行查看錯誤原因。

再次,把socket綁定到本機上,代碼如下:

  1. struct sockaddr_in sa;bzero(&sa, sizeof(sa));sa.sin_family = AF_INET;sa.sin_port = htons(EHCO_PORT);sa.sin_addr.s_addr = htons(INADDR_ANY);bzero(&(sa.sin_zero), 8);if(bind(socketfd, (struct sockaddr *)&sa, sizeof(sa))!= 0){printf("bind failed ");printf("errno=%d ", errno);exit(1);}else{printf("bind successfully ");} 

上面的代碼中,定義一個scokaddr_in 結構體變量sa,然后填機服務所要開通的端口號和地址。

sa.sin_family = AF_INET;

>表明地址類型

sa.sin_port = htons(EHCO_PORT);

>端口號為8080

sa.sin_addr.s_addr = htons(INADDR_ANY);

>表明綁定在本機

然后利用bind函數,把剛才已建立的socket作為參數,綁定起來。

綁定完成后,服務器要偵聽客戶端的連接,因此首先要完成偵聽設置這一過程,由listen函數實現,代碼如下:

  1. if(listen(socketfd ,MAX_CLIENT_NUM) != 0)...{printf("listen error ");exit(1);}else...{printf("listen successfully ");} 

listen(socketfd,MAX_CLIENT_NUM)表明在socketfd上偵聽,其中客戶個數最大值為MAX_CLIENT_NUM。

完成偵聽后,可以讓客戶與服務器進行連接了,服務想獲得客戶的請求,則需要通過 accept函數來獲得,同時,需要采用一個sockaddr_in結構體來獲得客戶的信息,代碼如下:

  1. int clientfd; struct sockaddr_in clientAdd;char buff[101];socklen_t len = sizeof(clientAdd);int closing =0;while( closing == 0 && (clientfd = accept(socketfd,  
  2. (struct sockaddr *)&clientAdd, &len)) >0 ){int n;while((n = recv(clientfd,buff, 100,0 )) > 0){printf("number of receive bytes = %d ", n);write(STDOUT_FILENO, buff, n);send(clientfd, buff, n, 0);buff[n] = '';if(strcmp(buff, "quit ") == 0){break;}else if(strcmp(buff, "close ") == 0){//server closingclosing = 1;printf("server is closing ");break;}}close(clientfd);} 

其中clientfd為客戶的socket,在服務器端,每接受一個客戶連接,都會返回一個客戶的socket描述符,服務器根據它與客戶進行通信。clientAdd為客戶地址信息的結構體,在accept函數中完成對它的填充,可依此得到客戶的地址信息。

  1. while( closing == 0 && (clientfd = accept(socketfd, (struct sockaddr *)&clientAdd, &len)) >0 ) 

等待第一個客戶,當第一個客戶的請求來到服務器后,該函數會返回,clientfd為客戶的socket描述符。

接著進行通信

while((n = recv(clientfd,buff, 100,0 )) > 0)

等待客戶的數據,收到數據后,在標準輸入出顯示接收的數據信息,并把它發送回給客戶:send(clientfd, buff, n, 0);

在這里,我們采用簡單的命令對通信進行控制,quit表示客戶要結束通信過程,而 close表示客戶請求關閉服務器,關閉只需使用 close函數即可完成。

下面是完整的代碼:

  1. #include #include #include #include #include #define EHCO_PORT 8080#define MAX_CLIENT_NUM 10int main(){int socketfd;socketfd = socket(AF_INET, SOCK_STREAM, 0);if(socketfd == -1){printf("errno=%d ", errno);exit(1);}else{printf("socket create successfully ");}struct sockaddr_in sa;bzero(&sa, sizeof(sa));sa.sin_family = AF_INET;sa.sin_port = htons(EHCO_PORT);sa.sin_addr.s_addr = htons(INADDR_ANY);bzero(&(sa.sin_zero), 8);if(bind(socketfd, (struct sockaddr *)&sa, sizeof(sa))!= 0){printf("bind failed ");printf("errno=%d ", errno);exit(1);}else{printf("bind successfully ");}//listenif(listen(socketfd ,MAX_CLIENT_NUM) != 0){printf("listen error ");exit(1);}else{printf("listen successfully ");}int clientfd;struct sockaddr_in clientAdd;char buff[101];socklen_t len = sizeof(clientAdd);int closing =0;while( closing == 0 && (clientfd = accept(socketfd, (struct sockaddr *)&clientAdd, &len)) >0 ){int n;while((n = recv(clientfd,buff, 100,0 )) > 0){printf("number of receive bytes = %d ", n);write(STDOUT_FILENO, buff, n);send(clientfd, buff, n, 0);buff[n] = '';if(strcmp(buff, "quit ") == 0){break;}else if(strcmp(buff, "close ") == 0){//server closingclosing = 1;printf("server is closing ");break;}}close(clientfd);}close(socketfd);return 0;} 

經過cc編譯后,即可運行,在這里我們寫的程序是服務器程序,要想完成通信,也得寫一個客戶端程吧???

呵呵,我們先把客戶端的程序放下來,先測測我們服務器程序吧,在這里,我們使用 telnet充當客戶端進行測試,telnet可以說是一個很好的客戶端程序,呵呵:

本機IP為192.168.0.69,整個通信過程如下:

  1. linyongting@linyongting:~$ telnet 192.168.0.69 8080Trying 192.168.0.69...Connected to 192.168.0.69.Escape character is '^]'.hello! This is my first packet.Can you reply to me?hello! This is my first packet.Can you reply to me?Ohh, U did it!Ohh, U did it!see U next time!!!see U next time!!!quitquitConnection closed by foreign host.linyongting@linyongting:~$ telnet 192.168.0.69 8080Trying 192.168.0.69...Connected to 192.168.0.69.Escape character is '^]'.closecloseConnection closed by foreign host. 

上面連接了兩次,第一次時,與服務器通信3次,每次發信息過去后,都收到與發出來一模一樣的信息。當用戶輸入quit的時候,服務端就會關閑與客戶通信的socket,通信結束。第二次客戶只輸入close,服務器響應后馬上關閉服務器,同時也關閉客戶端。下面是服務器的顯示內容:

  1. linyongting@linyongting:~/program/c$ ./echoServersocket create successfullybind successfullylisten successfully//第一次通信number of receive bytes = 53hello! This is my first packet.Can you reply to me?number of receive bytes = 16Ohh, U did it!number of receive bytes = 20see U next time!!!number of receive bytes = 6quit//第二次通信number of receive bytes = 7closeserver is closing 

當客戶端輸入quit時,只是客戶端關閉,服務器還接著為其它客服端服務。當客戶端輸入 close時,服務關閉。

當前出現的問題:

我們的服務器序程只能與一個客戶端進行通信,只能當客戶端發出quit命令關閉后才能與下一個客戶端通信。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 肇庆市| 南安市| 江源县| 黑龙江省| 西藏| 思南县| 阜康市| 高邮市| 黎川县| 嘉鱼县| 长泰县| 卓资县| 凤冈县| 察哈| 宜宾市| 调兵山市| 东乡县| 洪雅县| 万盛区| 黔东| 井冈山市| 云梦县| 博爱县| 鹿邑县| 四川省| 洪湖市| 枣庄市| 张家口市| 旅游| 辉县市| 西城区| 会东县| 金溪县| 越西县| 木兰县| 临泉县| 恩施市| 阜宁县| 壶关县| 定远县| 漳浦县|