| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6665 人关注过本帖
标题:端口复用时setsockopt函数的SO_REUSEADDR选项用不对
只看楼主 加入收藏
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
结帖率:91.43%
收藏
已结贴  问题点数:20 回复次数:5 
端口复用时setsockopt函数的SO_REUSEADDR选项用不对
每次端口复用bind的时候,就报错10013,提示端口正在使用,绑定失败。
setsockopt不是设置了SO_REUSEADDR选项以后,就可以把很多个套接字绑在同一个端口上吗?

自己查了下资料,但是越看越混乱。有说绑了就可以的,有说要等到TIME_WAIT状态才可以用,还有说只能UDP,不能TCP用。

越来越糊涂了,求指教,谢谢。

下面是代码
端口复用代码:
程序代码:
int main()
{
    WORD wVersionRequested=MAKEWORD(2,2);
    WSADATA wsaData;
    if(WSAStartup(wVersionRequested,&wsaData)!=0)
    {
       printf( "WSAStartup Error=%d\n" , WSAGetLastError()); 
       return 0;
    }
    SOCKET a=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP),b;
    int len;
    if(a==INVALID_SOCKET)
    {
      printf( "|socket Error=%d\n" , WSAGetLastError()); 
    }
    struct sockaddr_in a_add,b_add;
    a_add.sin_family=AF_INET;
    a_add.sin_port=htons(5555);
    a_add.sin_addr.S_un.S_addr=inet_addr("192.168.3.6");
    bool l=TRUE;
    setsockopt(a,SOL_SOCKET,SO_REUSEADDR,(char *)&l,sizeof(l));
    Sleep(1000);
    if(bind(a,(sockaddr *)&a_add,sizeof(a_add))==SOCKET_ERROR)
    {
       printf( "bind Error=%d\n" , WSAGetLastError()); 
       system("pause");
       return 0;
    } 
    if ( listen( a, 2 )== SOCKET_ERROR) 
    {
        printf( "listen Error=%d\n" , WSAGetLastError()); 
    system("pause");
    return 0;
    } 
    while(1)
    {
        len=sizeof(b_add);
        b=accept(a,(sockaddr *)&b_add,&len);
        CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)proc,(LPVOID)b,0,0);

    }
    closesocket(a);
    return 0;
}

void proc(LPVOID d)
{
     SOCKADDR_IN sa; //用于连接WEB 80 端口的SOCKET的结构(这个相当于客户端程序,向外服务端连接),
     //向外连接SOCKET只有一个
     sa.sin_family = AF_INET;
     sa.sin_addr.s_addr = inet_addr("127.0.0.1");
     sa.sin_port = htons(5555);
     SOCKET web = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
     connect(web,(sockaddr*)&sa,sizeof(sa)); //用此线程程序连接web
     char buf[4096];
     SOCKET ss = (SOCKET)d; //把传进来的处理连接的SOCKET赋给ss
     while(1)
     {
        int n = recv(ss,buf,4096,0);//从外部连接d(即SS)收到数据
        if(n==0) //没有数据
            break;
        if(n>0 && buf[0] =='y')
            ...
        else
            ...
    }
    closesocket(ss);
}


服务器代码:
程序代码:
int main() 
{ 
    WORD wVersionRequested= MAKEWORD( 2 ,2 ); 
    WSADATA wsaData; 
    if ( WSAStartup( wVersionRequested,& wsaData)!= 0 )
          return 0;

    //---------------创建用于监听的流式套接口s---------------
    SOCKET s= socket( AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if ( s== INVALID_SOCKET) 
    { 
        printf( "|socket Error=%d\n" , WSAGetLastError()); 
        return 0;
    } 
    //---------------绑定,使用bind()----------------------
    struct sockaddr_in Sadd; 
    Sadd.sin_family= AF_INET; 
    Sadd.sin_port= htons( 5555 ); 
    Sadd.sin_addr.S_un.S_addr= inet_addr( "192.168.3.6" );   
    if ( bind( s,( sockaddr*)& Sadd, sizeof ( Sadd))== SOCKET_ERROR) 
    { 
        printf( "bind Error=%d\n" , WSAGetLastError()); 
        return 0;
    } 
    //---------------监听-------------
    if ( listen( s, 2 )== SOCKET_ERROR) 
    { 
        printf( "listen Error=%d\n" , WSAGetLastError()); 
        return 0;
    } 
    //----------------循环接受客户的连接请求---------------------------
    struct sockaddr_in Cadd; 
    int caddLen= sizeof ( Cadd);    
    while ( TRUE ) 
    { 
        SOCKET c;
        c= accept( s,( sockaddr*)& Cadd,& caddLen); 
        if ( c== INVALID_SOCKET) 
        { 
            printf( "|accept Error=%d\n" , WSAGetLastError()); 
            return 0;
        } 
    while(1)
    {
        ......
    }
    closesocket( c); 
    } 
    closesocket( s); 
    WSACleanup(); 
    return 0 ;
}
搜索更多相关主题的帖子: 资料 
2016-03-09 23:47
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:14 
花费了我好长时间,总于可以编译成功了,然后发现看不懂你的代码想干什么,因为两段代码都是listen/accept
退一步,不看了,直接运行,也不知道怎样重现你的bug,即根本不知道你想解决什么问题
2016-03-10 09:13
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 2楼 rjsp
本来是有三段程序,分别是服务端、客户端和端口复用。
服务端和客户端是实现会话和下载功能,我怕程序太长不好看,就没放客户端的代码,服务端的代码也阉割了一部分。
服务端绑定的5555端口,我想端口复用也绑定5555端口,然后截获客户端的信息,判断有没有自己想要的东西(proc实现),若有了,就截下来,自己和客户端通信;若没有,则转发127.0.0.1,让其交由服务器和客户端通信,并继续“监听”(做中转站)。
在服务器和客户端简历通信后,启动端口复用程序。端口复用程序在setsockopt之后的bind出错,绑定不上5555端口。
2016-03-10 16:22
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 2楼 rjsp
我理解,端口复用既然要截信息,那它应该也是服务器的功能,就应该是 listen/accept
2016-03-10 16:28
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
回复 2楼 rjsp
还是没说清楚,就是服务器客户端已经互相通信了,我怎么绑定它们通信的端口,自己做服务器。
2016-03-10 16:30
lyl930130
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:323
专家分:111
注 册:2013-5-13
收藏
得分:0 
发现是自己理解错了。问题不是出在端口复用,而是出在
程序代码:
SOCKADDR_IN sa; //用于连接WEB 80 端口的SOCKET的结构(这个相当于客户端程序,向外服务端连接),
     //向外连接SOCKET只有一个
     sa.sin_family = AF_INET;
     sa.sin_addr.s_addr = inet_addr("127.0.0.1");
     sa.sin_port = htons(5555);
     SOCKET web = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
     connect(web,(sockaddr*)&sa,sizeof(sa)); //用此线程程序连接web

但是出错原因还是没搞明白
2016-03-21 16:57
快速回复:端口复用时setsockopt函数的SO_REUSEADDR选项用不对
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030218 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved