最新公告
  • 欢迎您光临波比源码,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 服务器如何给多个客户端分配端口号

    在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);
    }

    波比源码 – 精品源码模版分享 | www.bobi11.com
    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

    波比源码 » 服务器如何给多个客户端分配端口号

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    波比源码
    一个高级程序员模板开发平台
    升级波友尊享更多特权立即升级