![]() |
#2
rjsp2016-03-10 09:13
|
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);
}
{
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 ;
}
{
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 ;
}