linux listen的意思是監聽,listen指的是監聽來自客戶端的tcp socket的連接請求;listen函數在一般在調用bind之后和調用accept之前調用,它的函數原型是“int listen ?(int sockfd, ?int backlog)”。
本教程操作環境:linux5.9.8系統、Dell G3電腦。
linux listen 什么意思?
linux下listen函數
listen:監聽來自客戶端的tcp socket的連接請求
listen函數在一般在調用bind之后-調用accept之前調用,它的函數原型是:
#include<sys>?? int?listen??(??int?sockfd,??int?backlog??)</sys>
參數sockfd是被listen函數作用的套接字
參數backlog是偵聽隊列的長度。 ?在進程正在處理一個連接請求的時候,可能還存在其它的連接請求。因為TCP連接是一個過程,所以可能存在一種半連接的狀態,有時由于同時嘗試連接的用戶過多,使得服務器進程無法快速地完成連接請求。如果這個情況出現了,服務器進程希望內核如何處理呢?內核會在自己的進程空間里維護一個隊列以跟蹤這些完成的連接但服務器進程還沒有接手處理的連接(還沒有調用accept函數的連接),這樣的一個隊列內核不可能讓其任意大,所以必須有一個大小的上限。這個backlog告訴內核使用這個數值作為上限。
返回值 |
成功 |
失敗 |
是否設置errno |
0 |
?1 |
是 |
錯誤信息:
EADDRINUSE:另一個socket也在監聽同一個端口。
EBADF:參數sockfd為非法的文件描述符。
ENOTSOCK:參數sockfd不是文件描述符。
EOPNOTSUPP:套接字類型不支持listen操作。
實例:
#include?<stdio.h> #include?<stdlib.h> #include?<errno.h> #include?<string.h> #include?<sys> #include?<netinet> #include?<sys> #include?<sys> int?main() { int?sockfd,new_fd; struct?sockaddr_in?my_addr; struct?sockaddr_in?their_addr; int?sin_size; //建立TCP套接口 if((sockfd?=?socket(AF_INET,SOCK_STREAM,0))==-1) { printf("create?socket?error"); perror("socket"); exit(1); } //初始化結構體,并綁定2323端口 my_addr.sin_family?=?AF_INET; my_addr.sin_port?=?htons(2323); my_addr.sin_addr.s_addr?=?INADDR_ANY; bzero(&(my_addr.sin_zero),8); //綁定套接口 if(bind(sockfd,(struct?sockaddr?*)&my_addr,sizeof(struct?sockaddr))==-1) { perror("bind?socket?error"); exit(1); } //創建監聽套接口??監聽隊列長度為10 if(listen(sockfd,10)==-1) { perror("listen"); exit(1); } //等待連接 while(1) { sin_size?=?sizeof(struct?sockaddr_in); printf("server?is?run./n"); //如果建立連接,將產生一個全新的套接字 if((new_fd?=?accept(sockfd,(struct?sockaddr?*)&their_addr,&sin_size))==-1) { perror("accept"); exit(1); } printf("accept?success./n"); //生成一個子進程來完成和客戶端的會話,父進程繼續監聽 if(!fork()) { printf("create?new?thred?success./n"); //讀取客戶端發來的信息 int?numbytes; char?buff[256]; memset(buff,0,256); if((numbytes?=?recv(new_fd,buff,sizeof(buff),0))==-1) { perror("recv"); exit(1); } printf("%s",buff); //將從客戶端接收到的信息再發回客戶端 if(send(new_fd,buff,strlen(buff),0)==-1) perror("send"); close(new_fd); exit(0); } close(new_fd); } close(sockfd); } #include?<stdio.h> #include?<stdlib.h> #include?<string.h> #include?<netdb.h> #include?<sys> #include?<sys> int?main(int?argc,char?*argv[]) { int?sockfd,numbytes; char?buf[100]; struct?sockaddr_in?their_addr; //int?i?=?0; //將基本名字和地址轉換 //he?=?gethostbyname(argv[1]); //建立一個TCP套接口 if((sockfd?=?socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); printf("create?socket?error.建立一個TCP套接口失敗"); exit(1); } //初始化結構體,連接到服務器的2323端口 their_addr.sin_family?=?AF_INET; their_addr.sin_port?=?htons(2323); //?their_addr.sin_addr?=?*((struct?in_addr?*)he->h_addr); inet_aton(?"127.0.0.1",?&their_addr.sin_addr?); bzero(&(their_addr.sin_zero),8); //和服務器建立連接 if(connect(sockfd,(struct?sockaddr?*)&their_addr,sizeof(struct?sockaddr))==-1) { perror("connect"); exit(1); } //向服務器發送數據 if(send(sockfd,"hello!socket.",6,0)==-1) { perror("send"); exit(1); } //接受從服務器返回的信息 if((numbytes?=?recv(sockfd,buf,100,0))==-1) { perror("recv"); exit(1); } buf[numbytes]?=?'/0'; printf("Recive?from?server:%s",buf); //關閉socket close(sockfd); return?0; }</sys></sys></netdb.h></string.h></stdlib.h></stdio.h></sys></sys></netinet></sys></string.h></errno.h></stdlib.h></stdio.h>
推薦學習:《linux視頻教程》
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END
喜歡就支持一下吧
相關推薦