日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 服務器如何給多個客戶端分配端口號

服務器如何給多個客戶端分配端口號

來源:程序員人生   發布時間:2014-12-15 09:13:13 閱讀次數:6181次

在1臺計算機上,使用socket通訊時,不同進程辨別網絡通訊的連接依托3個參數:通訊所用協議、地址IP、端口號。

服務器端來講,通過bind、listen,以后accept建立新的連接,accept返回新連接的句柄,這樣就建立了1條連接。那末新建立的連接使用的端口號是不是和listen所用端口號相同呢?之前我1直以為服務器會隨機分配1個新的端口號來使用,后來發現錯了。

由于1、現在使用多路IO復用epoll等,配置好點的服務器可以支持數10萬個并發連接,端口號為16位,最多才2^16⑴,且加上1些經常使用的端口號不能使用,可用的端口號都沒那末多。2、現在服務器大多使用防火墻,防火墻只對特定端口開放。如果accept隨機分配端口號,會不能通過防火墻。

TCP/IP協議中,IP協議是端到真個協議,它只是負責把把數據發送到端,交付給上層而已。運輸層TCP、UDP加上了端口號,目的是辨別不同的利用。其中TCP還實現了流量控制、可靠傳輸等,而UDP只是應當是沒有對IP層數據進行處理了。

在以往的知識中,我知道1個利用程序只能使用1個端口號,如果accept返回的句柄還是使用listen的端口號,那末怎樣實現通訊呢?如果建立多個連接,利用程序怎樣區收到的信息來自哪一個客戶端呢?

現在才理解到accept返回的句柄建立的連接包括4部份:源IP、源端口號、目的IP、目的端口號。這樣在1個利用程序中,就算和多個客戶端建立連接,在收到數據后,利用程序通過目的IP和目的端口號也能辨別是哪1條連接。

通過1個echo服務器來驗證1下,client和server都在同1臺機器上:

服務器監聽8000端口,在未建立連接時,可以看到在監聽8000


在通過1個客戶端建立連接后,可以看到建立了1條連接,服務器真個端口號是8000,監聽的還是8000。


在連接1個客戶端,可以看到建立了兩條連接,服務器端都是使用8000,監聽的還是8000。


下面是server端代碼:

#include<stdio.h> #include<sys/socket.h> #include<unistd.h> #include<errno.h> #include<netinet/in.h> void str_echo(int sockfd) { int n; char buf[1024]; again: while((n=read(sockfd,buf,1024))>0) { write(sockfd,buf,n); } if(n<0&&errno==EINTR) goto again; else if(n<0) printf("str_error:read error"); } int main(int argc, char **argv) { int listenfd, connfd; pid_t childid; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; listenfd=socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//host IP servaddr.sin_port=htons(8000);//port bind(listenfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); listen(listenfd,5);//最多處理5個監聽 for(;;) { clilen=sizeof(cliaddr); //進場阻塞在accept上 connfd=accept(listenfd, (struct sockaddr*)&cliaddr,&clilen); if(childid=fork()==0)//child { close(listenfd);//在子進程中關閉監聽 str_echo(connfd);//處理監聽的連接 exit(0); } } close(listenfd); }

客戶端代碼:

#include<stdio.h> #include<sys/socket.h> #include<netinet/in.h> #include<unistd.h> void str_cli(FILE *fp, int sockfd) { char sendline[1024],recvline[1024]; while(fgets(sendline, 1024, fp)!=NULL) { //發給Server write(sockfd,sendline,sizeof(sendline)); //讀Server if(read(sockfd,recvline,1024)==0) { printf("str_cli:server terminated prematurely "); exit(0); } //fputs(recvline,stdout); printf("%s",recvline); } } int main(int argc, char **argv) { int sockfd; struct sockaddr_in servaddr; if(argc!=2) { printf("usage:client IPaddress "); exit(0); } sockfd=socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(8000); //把輸入的IP存到sin_addr中 inet_pton(AF_INET,argv[1],&servaddr.sin_addr); printf("server IP:%s ",argv[1]); //建立連接 connect(sockfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); str_cli(stdin,sockfd); exit(0); }


生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美成人精品在线观看 | 精品久久成人 | 日本精品视频一区二区 | av看片 | 免费的av | 欧美视频在线一区 | 成人a级网站 | 日韩美女一区 | 婷婷丁香六月 | 欧美成人自拍 | 欧美一区二区三区视频在线 | 欧美色欧美亚洲另类七区 | 国产精品视屏 | 久久国产精品久久 | 国产精品毛片一区二区三区 | 欧美淫视频 | 色综综| av片免费在线播放 | 91精品国产乱码久久久久久 | 天天综合网天天综合色 | 91精品国产日韩91久久久久久 | 欧美成人免费网站 | 中文字幕在线视频一区 | 亚洲精品高潮 | 国产专区在线 | 蜜桃视频一区二区 | 亚洲精品亚洲人成人网 | h片在线观看视频免费免费 日韩国产一区二区 | 免费黄色官网 | 美女被免费喷白浆视频 | 久久久久美女 | 亚洲视频在线观看视频 | 久久中文字幕一区二区 | 久久久综合色 | 日韩美女在线看免费观看 | 污网站免费 | 看中国黄色毛片 | av一区二区三区 | 91精产品一区一区三区 | 久久久久久国产免费 | 免费日韩一区二区 |