• socket


    网友vmstat多次提出了这个问题:SO_REUSEADDR有什么用处和怎么使用。而且很多网友在编写网络程序时也会遇到这个问题。所以特意写了这么一篇文章,希望能够解答一些人的疑难。

    其实这个问题在Richard Stevens的《Unix网络编程指南》卷一里有很详细的解答(中文版P166-168页)。这里我只是写几个基本的例子来验证这个问题。
    首先声明一个问题:当两个socket的address和port相冲突,而你又想重用地址和端口,则旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性,只有两者之一有这个特性还是有问题的。
    SO_REUSEADDR可以用在以下四种情况下。
    (摘自《Unix网络编程》卷一,即UNPv1)
    1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你启动的程序的socket2要占用该地址和端口,你的程序就要用到该选项。
    2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可以测试这种情况。
    3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。这和2很相似,区别请看UNPv1。

    4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。

    #include <stdio.h>  
    #include <stdlib.h>  
      
    #include <sys/socket.h>    
    #include <netinet/in.h>    
    #include <arpa/inet.h>    
    #include <sys/types.h>    
    #include <unistd.h>    
    #include <string.h>
    #include <time.h>  
    #define MAXLINE 100  
      
    int main(int argc, char** argv)  
    {  
        int listenfd,connfd;  
        struct sockaddr_in servaddr;  
        char buff[MAXLINE+1];  
        time_t ticks;  
        unsigned short port;  
        int flag=1,len=sizeof(int);  
      
        port=10013;  
        if( (listenfd=socket(AF_INET,SOCK_STREAM,0)) == -1)  
        {  
            perror("socket");  
            exit(1);  
        }  
        bzero(&servaddr,sizeof(servaddr));  
        servaddr.sin_family=AF_INET;  
        servaddr.sin_addr.s_addr=htonl(INADDR_ANY);  
        servaddr.sin_port=htons(port);  
        /**/if( setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &flag, len) == -1)  
        {  
            perror("setsockopt");  
            exit(1);  
        }  
        if( bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) ==-1)  
        {  
            perror("bind");  
            exit(1);  
        }  
        else  
            printf("bind call OK!
    ");  
        if( listen(listenfd,5) == -1)  
        {  
            perror("listen");  
            exit(1);  
        }  
      
        for(;;) {  
            if( (connfd=accept(listenfd,(struct sockaddr*)NULL,NULL)) == -1)  
            {  
                perror("accept");  
                exit(1);  
            }  
            if( fork() == 0)/**//*child process*/  
            {  
                close(listenfd);/**//*这句不能少,原因请大家想想就知道了。*/  
                ticks=time(NULL);  
                snprintf(buff,100,"%.24s
    ",ctime(&ticks));  
                write(connfd,buff,strlen(buff));  
                close(connfd);  
                sleep(1);  
                execlp("f1-9d",NULL);  
                perror("execlp");  
                exit(1);  
            }  
            close(connfd);  
            exit(0);/**//* end parent*/  
        }  
    }  

    相关链接:

    http://leafghost.blogspot.com/2010/04/socketsoreuseaddr.html

    端口重用引发的惨案

    http://rdc.taobao.com/blog/cs/?p=1195

     转自:http://blog.csdn.net/xsckernel/article/details/8159292

  • 相关阅读:
    echars柱状图修改每条柱的颜色
    vue打开到新页面,并传递参数
    彻底了解websocket原理
    bind和on的区别
    Vue如何更新子组件
    Vue父子组件生命过程
    使用css3实现动画来开启GPU加速
    前端技术体系
    Vue中的~(静态资源处理)
    垂直居中的办法小结
  • 原文地址:https://www.cnblogs.com/yorkyang/p/7904358.html
Copyright © 2020-2023  润新知