端口复用时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 ; }