基于TCP的socket编程网络掉线重连

来源:互联网 发布:网络买卖 编辑:程序博客网 时间:2024/05/23 05:08
基于TCP的socket编程 
sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字。 
正在装载数据… 
在这个程序中,将两个工程添加到一个工作区。要链接一个ws2_32.lib的库文件。 
服务器端编程的步骤: 
1:加载套接字库,创建套接字(WSAStartup()/socket()); 
2:绑定套接字到一个IP地址和一个端口上(bind()); 
3:将套接字设置为监听模式等待连接请求(listen()); 
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept()); 
5:用返回的套接字和客户端进行通信(send()/recv()); 
6:返回,等待另一连接请求; 
7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。 
服务器端代码如下: 
#include <stdio.h> 
#include <Winsock2.h> 
void main() 
{ 
WORD wVersionRequested; 
WSADATA wsaData; 
int err; 
wVersionRequested = MAKEWORD( 1, 1 ); 
err = WSAStartup( wVersionRequested, &wsaData ); 
if ( err != 0 ) { 
return; 
} 
if ( LOBYTE( wsaData.wVersion ) != 1 || 
HIBYTE( wsaData.wVersion ) != 1 ) { 
WSACleanup( ); 
return;  
} 
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); 
SOCKADDR_IN addrSrv; 
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); 
addrSrv.sin_family=AF_INET; 
addrSrv.sin_port=htons(6000); 
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 
listen(sockSrv,5); 
SOCKADDR_IN addrClient; 
int len=sizeof(SOCKADDR); 
while(1) 
{ 
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); 
char sendBuf[50]; 
sprintf(sendBuf,"Welcome s to here!",inet_ntoa(addrClient.sin_addr)); 
send(sockConn,sendBuf,strlen(sendBuf) 1,0); 
char recvBuf[50]; 
recv(sockConn,recvBuf,50,0); 
printf("s\n",recvBuf); 
closesocket(sockConn); 
} 
} 

客户端编程的步骤: 
1:加载套接字库,创建套接字(WSAStartup()/socket()); 
2:向服务器发出连接请求(connect()); 
3:和服务器端进行通信(send()/recv()); 
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。 
客户端的代码如下: 
#include <stdio.h> 
#include <Winsock2.h> 
void main() 
{ 
WORD wVersionRequested; 
WSADATA wsaData; 
int err; 
wVersionRequested = MAKEWORD( 1, 1 ); 
err = WSAStartup( wVersionRequested, &wsaData ); 
if ( err != 0 ) { 
return; 
} 
if ( LOBYTE( wsaData.wVersion ) != 1 || 
HIBYTE( wsaData.wVersion ) != 1 ) { 
WSACleanup( ); 
return;  
} 
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); 
SOCKADDR_IN addrSrv; 
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); 
addrSrv.sin_family=AF_INET; 
addrSrv.sin_port=htons(6000); 
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 
char recvBuf[50]; 
recv(sockClient,recvBuf,50,0); 
printf("s\n",recvBuf); 
send(sockClient,"hello",strlen("hello") 1,0); 
closesocket(sockClient); 
WSACleanup(); 
} 
请问:  
    我的client,server都是同步,想用tcp协议提供的heartbeat机制检测网络连接是否中断。网上找来如下代码,请问如和使用?是在client,server的socket创建好后都要加如下代码还是只需要一方加上就行了?另外通过如下代码我recv受到的数据包应该是什么内容?下面代码需要写在一个线程中不停的判断WSAIoctl返回值吗?请高人指点。  
//设置KeepAlive    
BOOL       bKeepAlive       =       TRUE;    
nRet       =       ::setsockopt(m_sockDesc,       SOL_SOCKET,       SO_KEEPALIVE,       (char*)&bKeepAlive,       sizeof(bKeepAlive));    
if       (nRet       !=0)    
{    
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Socket       SetOpt       failed   ",       WSAGetLastError());    
return       FALSE;    
}    
//设置KeepAlive检测时间和次数    
TCP_KEEPALIVE       inKeepAlive       =       {0};       //输入参数    
unsigned       long       ulInLen       =       sizeof(TCP_KEEPALIVE);            

TCP_KEEPALIVE       outKeepAlive       =       {0};       //输出参数    
unsigned       long       ulOutLen       =       sizeof(TCP_KEEPALIVE);            

unsigned       long       ulBytesReturn       =       0;    
//设置socket的keep       alive为10秒,并且发送次数为3次    
inKeepAlive.onoff       =       1;        
inKeepAlive.keepaliveinterval       =       10000;       //两次KeepAlive探测间的时间间隔    
inKeepAlive.keepalivetime       =       3;       //开始首次KeepAlive探测前的TCP空闭时间    
nRet       =       WSAIoctl(m_sockDesc,        
SIO_KEEPALIVE_VALS,    
(LPVOID)&inKeepAlive,    
ulInLen,    
(LPVOID)&outKeepAlive,    
ulOutLen,    
&ulBytesReturn,    
NULL,    
NULL);    
if(SOCKET_ERROR       ==       nRet)    
{    
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Nonblocking       socket       call       error   ",       WSAGetLastError());    
return       FALSE;    
}    
心跳是逻辑应用层的东西,需要自己实现,一般为自定义,当socket空闲时,发送心跳包,报文件格式自定义!  
我现在也遇到心跳检测的问题.网上查没查到,感觉大多比较笼统,就自己做吧.  
自己根据需要想了一下.客户端发自定义的心跳包,服务器端接收到心跳包向客户端返回个东西  
然后客户端再处理.实现上是可以的.  
因为水平有限,还是想学习一下标准的做法  
心跳检测需要以下步骤:  
1       客户端每隔一个时间间隔发生一个探测包给服务器  
2       客户端发包时启动一个超时定时器  
3       服务器端接收到检测包,应该回应一个包  
4       如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器  
5       如果客户端的超时定时器超时,请问:  
    我的client,server都是同步,想用tcp协议提供的heartbeat机制检测网络连接是否中断。网上找来如下代码,请问如和使用?是在client,server的socket创建好后都要加如下代码还是只需要一方加上就行了?另外通过如下代码我recv受到的数据包应该是什么内容?下面代码需要写在一个线程中不停的判断WSAIoctl返回值吗?请高人指点。  
//设置KeepAlive    
BOOL       bKeepAlive       =       TRUE;    
nRet       =       ::setsockopt(m_sockDesc,       SOL_SOCKET,       SO_KEEPALIVE,       (char*)&bKeepAlive,       sizeof(bKeepAlive));    
if       (nRet       !=0)    
{    
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Socket       SetOpt       failed   ",       WSAGetLastError());    
return       FALSE;    
}    
//设置KeepAlive检测时间和次数    
TCP_KEEPALIVE       inKeepAlive       =       {0};       //输入参数    
unsigned       long       ulInLen       =       sizeof(TCP_KEEPALIVE);        
TCP_KEEPALIVE       outKeepAlive       =       {0};       //输出参数    
unsigned       long       ulOutLen       =       sizeof(TCP_KEEPALIVE);            
unsigned       long       ulBytesReturn       =       0;    
//设置socket的keep       alive为10秒,并且发送次数为3次    
inKeepAlive.onoff       =       1;        
inKeepAlive.keepaliveinterval       =       10000;       //两次KeepAlive探测间的时间间隔    
inKeepAlive.keepalivetime       =       3;       //开始首次KeepAlive探测前的TCP空闭时间    

nRet       =       WSAIoctl(m_sockDesc,        
SIO_KEEPALIVE_VALS,    
(LPVOID)&inKeepAlive,    
ulInLen,    
(LPVOID)&outKeepAlive,    
ulOutLen,    
&ulBytesReturn,    
NULL,    
NULL);    
if(SOCKET_ERROR       ==       nRet)    
{    
sprintf(m_pszError,       "Winsock       error       :       %s       (Error       Code       %d)\n   ",       "Nonblocking       socket       call       error   ",       WSAGetLastError());    
return       FALSE;    
}    

心跳检测需要以下步骤:  
1       客户端每隔一个时间间隔发生一个探测包给服务器  
2       客户端发包时启动一个超时定时器  
3       服务器端接收到检测包,应该回应一个包  
4       如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器  
5       如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了  

依然没有收到应答包,则说明服务器挂了  
DWORD   NetSessionEnum(   LPSTR,    
DWORD,    
LPBYTE,    
DWORD,    
LPDWORD,    
LPDWORD   )    
参数1:   NULL表示枚举本机的网络连接    
参数2:   不详.在枚举中是常量0x32.    
参数3:   存放信息的缓冲区指针    
参数4:   缓冲区长度    
参数5:   指向返回连接个数    
参数6:   指向总共连接个数    
Top 
在WINDOWS95&WINDOWS98下如何关闭网络连接      
   --------------------------------------------------------------------------------    
如果你有这个方面的问题请到C/C++去提问或发表你的意见        来源:论坛转载无法确定出处,如有版权问题请与我们联系      在WINDOWS95&WINDOWS98下如何关闭网络连接    
一.问题提出:       每当你通过WINDOWS95或WINDOWS98访问"网上邻居"时,系统自动的建立了两    
台机器之间的网络连接关系,但是在访问结束后,并不自动的断开网络连接,    
所以有时我们关闭WINDOWS系统时,会弹出一个对话框,询问是否关闭网络连    
接,在回答"YES"后,才真正开始关闭计算机.    
程序员编制系统关闭程序时,就需要考虑这种情况,虽然SDK提供了关机的API:    
ExitWindowsEx()和ExitWindows(),但实际应用中我发现,在指定FORCE关机时    
在特定情况下会出问题.所以,必须想办法首先断开网络连接.       
二.编程接口:       
WINDOWS95及WINDOWS98提供的这方面的网络编程接口在SVRAPI.DLL中,利用它    
我们可以列举出当前网络连接状态,控制或删除网络连接.WINDOWS附件中的    
NETWATCH.EXE工具就是这样实现的.    
也许您会问,NetAPI的详细说明在开发工具的SDK文档中很详细了,没有必要在    
此演示.但是,在查寻了很多资料后,我不得不说:MSDN中有关NetAPI的部分说    
明是错误的,至少是不完整而且含混不清的,可以说,依靠这些文档,你不能实    
现全部的功能!下面的代码是本人自己分析得来,使用后,您会发现正确的应用    
和文档说明有多么大的差距.       
三.API声明:       
关闭网络连接的实现方法分两步:   枚举出当前所有的网络连接状况;   依次    
断开枚举出的网络连接.       
1.枚举出当前所有的网络连接状况:    
依照开发帮助文档,这个API是这样的:    
NET_API_STATUS   NetSessionEnum(    
LPWSTR   servername,      
LPWSTR   UncClientName,      
LPWSTR   username,      
DWORD   level,      
LPBYTE   *bufptr,      
DWORD   prefmaxlen,      
LPDWORD   entriesread,      
LPDWORD   totalentries,      
LPDWORD   resume_handle      
);       
但是,实际情况是,在WINDOWS95和WINDOWS98平台下,    
这样调用根本就无法连接上库文件.真正的API声明应该是:    
DWORD   NetSessionEnum(   LPSTR,    
DWORD,    
LPBYTE,    
DWORD,    
LPDWORD,    
LPDWORD   )    
参数1:   NULL表示枚举本机的网络连接    
参数2:   不详.在枚举中是常量0x32.    
参数3:   存放信息的缓冲区指针    
参数4:   缓冲区长度    
参数5:   指向返回连接个数    
参数6:   指向总共连接个数    
可见,参数个数完全不同,另外参数意义也发生了变化.    
     
2.依次断开枚举出的网络连接:    
还算幸运的是,断开网络连接的API声明是正确的:    
NET_API_STATUS   NetSessionDel(    
LPWSTR   servername,      
LPWSTR   UncClientName,      
LPWSTR   username   );    
不过要注意的是,第2个和第3个参数的内容需要    
从枚举得到的缓冲区中去取.具体方法参见程序.    
     
四.源代码:    
     
以下是实现断开网络连接的子程序,你可以方便的把它们加入到自己的项目中    
去,而不用和我一样浪费时间去研究到底怎样实现网络枚举了.    
     
注:由于本程序只实际用到了一个SVRAPI.DLL中的函数声明,简便期间,我没有    
用原有的头文件,自己定义一下就可以了.    
     
///////////////////////////////////////////////////////////////////    
//   File:   NetClose.H    
//   Version:   1.01    
     
#define   NETBUFF_SIZE   0x208    
     
#define   NetSessionEnum_PROFILE   (   DWORD   (__stdcall   *)   (   LPSTR,   DWORD,   LPBYTE,   DWORD,   LPDWORD,   LPDWORD   )   )    
#define   NetSessionDel_PROFILE   (   DWORD   (__stdcall   *)   (   LPSTR,   LPSTR,   DWORD   )   )    
///////////////////////////////////////////////////////////////////    
//   File:   NetClose.CPP    
//   Version:   1.01    
///////////////////////////////////////////////////////////////////    
//   Define:   BOOL   NetCloseAll(   VOID   )    
//   Parameters:   None    
//   Return:   TRUE   or   FALSE    
//    
//   Author:   Mr.Huang   fei    
//   Time:   5/7/1998    
//   Note:   Can   only   be   used   on   Windows95   &   Windows98    
//   Remark:   Close   all   network   conneCTions    
///////////////////////////////////////////////////////////////////    
BOOL   NetCloseAll(   VOID   )    
{    
BYTE   byBuff[NETBUFF_SIZE];    
DWORD   dwNetRet   =   0;;    
DWORD   i   =   0;    
DWORD   dwEntries   =   0;    
DWORD   dwTotalEntries   =   0;    
LPSTR   szClient   =   NULL;    
DWORD   dwUserName   =   0;    
BOOL   bRet   =   FALSE;    
LPBYTE   lpbyBuff   =   (LPBYTE)byBuff;    
     
DWORD   (__stdcall   *   hookNetSessionEnum)(   LPSTR,   DWORD,   LPBYTE,   DWORD,   LPDWORD,   LPDWORD   );    
DWORD   (__stdcall   *   hookNetSessionDel)(   LPSTR,   LPSTR,   DWORD   );    
     
HINSTANCE   hMod   =   LoadLibrary(   "SVRAPI.DLL"   );    
if(   hMod   !=   NULL   )    
{    
//   Get   the   address   of   function    
hookNetSessionEnum   =   NetSessionEnum_PROFILE    
GetProcAddress    
(   hMod,   TEXT("NetSessionEnum")   );    
hookNetSessionDel   =   NetSessionDel_PROFILE    
GetProcAddress    
(   hMod,   TEXT("NetSessionDel")   );    
     
if(   (   hookNetSessionDel   !=   NULL   )   &&    
(   hookNetSessionEnum   !=   NULL   )   )    
{    
dwNetRet   =   hookNetSessionEnum(   NULL,    
0x32,   byBuff,    
NETBUFF_SIZE,   &dwEntries,    
&dwTotalEntries   );    
if(   dwNetRet   ==   0   )    
{    
bRet   =   TRUE;    
for(   i=0;   i   <   dwTotalEntries;   i++   )    
{    
szClient   =   (LPSTR)(((DWORD   *)    
lpbyBuff)[0]);    
dwUserName   =   ((DWORD   *)lpbyBuff)[2];    
dwNetRet   =   hookNetSessionDel(   NULL,    
szClient,   dwUserName   );    
if(   dwNetRet   !=   0   )    
{    
bRet   =   FALSE;    
break;    
}    
lpbyBuff   +=   26;    
}    
}   //   NetSessionEnum(...)    
else    
bRet   =   FALSE;    
}   //   GetProcAddress(...)    
else    
bRet   =   FALSE;    
     
FreeLibrary(   hMod   );    
}   //   LoadLibrary(...)    
return   bRet;    
}    
     
五.总结:    
     
以上是开发过程中的一点经验,希望对大家有所帮助,有不对的地方请谅解并    
指出.另外,众所周知Microsoft的开发文档有相当一部分是未公开的,这些未    
公开信息有时会给我们造成很大的困难,在此希望有类似体验的程序开发者    
把自己的经验写出来,让后来者少走一些弯路.    
8 楼sevencat(七猫)回复于 2003-10-05 15:47:13 得分 0 要稍微翻译一下吗?InternetGetConnectedState这个函数获得当前系统的连接状态。    
参数    
     
lpdwFlags   是一个指向整数的指针。    
获取的状态就放在这里面    
     
INTERNET_CONNECTION_CONFIGURED   有一个internet上的无效连接,不过当前可能不工作。    
INTERNET_CONNECTION_LAN   Local   用当地网络连上互连网的    
INTERNET_CONNECTION_MODEM   用MODEM上网的    
INTERNET_CONNECTION_MODEM_BUSY   不使用了。    
INTERNET_CONNECTION_OFFLINE   脱状态下。    
INTERNET_CONNECTION_PROXY   用代理服务器连上网的。      
INTERNET_RAS_INSTALLED   用了RAS了。Top 
2 楼Skt32(荒城之月)回复于 2003-10-03 21:08:49 得分 5DWORD   NetSessionEnum(   LPSTR,    
DWORD,    
LPBYTE,    
DWORD,    
LPDWORD,    
LPDWORD   )    
参数1:   NULL表示枚举本机的网络连接    
参数2:   不详.在枚举中是常量0x32.    
参数3:   存放信息的缓冲区指针    
参数4:   缓冲区长度    
参数5:   指向返回连接个数    
参数6:   指向总共连接个数    
Top 

在WINDOWS95&WINDOWS98下如何关闭网络连接      
一.问题提出:    
     
每当你通过WINDOWS95或WINDOWS98访问"网上邻居"时,系统自动的建立了两   台机器之间的网络连接关系,但是在访问结束后,并不自动的断开网络连接,   所以有时我们关闭WINDOWS系统时,会弹出一个对话框,询问是否关闭网络连   接,在回答"YES"后,才真正开始关闭计算机.   程序员编制系统关闭程序时,就需要考虑这种情况,虽然SDK提供了关机的API:   ExitWindowsEx()和ExitWindows(),但实际应用中我发现,在指定FORCE关机时    
在特定情况下会出问题.所以,必须想办法首先断开网络连接.    
     
二.编程接口:    
     
WINDOWS95及WINDOWS98提供的这方面的网络编程接口在SVRAPI.DLL中,利用它   我们可以列举出当前网络连接状态,控制或删除网络连接.WINDOWS附件中的 NETWATCH.EXE工具就是这样实现的.    
也许您会问,NetAPI的详细说明在开发工具的SDK文档中很详细了,没有必要在 此演示.但是,在查寻了很多资料后,我不得不说:MSDN中有关NetAPI的部分说   明是错误的,至少是不完整而且含混不清的,可以说,依靠这些文档,你不能实   现全部的功能!下面的代码是本人自己分析得来,使用后,您会发现正确的应用    
和文档说明有多么大的差距.       
三.API声明:       
关闭网络连接的实现方法分两步:   枚举出当前所有的网络连接状况;   依次 断开枚举出的网络连接.    
     
1.枚举出当前所有的网络连接状况:    
依照开发帮助文档,这个API是这样的:    
NET_API_STATUS   NetSessionEnum(    
LPWSTR   servername,      
LPWSTR   UncClientName,      
LPWSTR   username,      
DWORD   level,      
LPBYTE   *bufptr,      
DWORD   prefmaxlen,      
LPDWORD   entriesread,      
LPDWORD   totalentries,      
LPDWORD   resume_handle      
);    
     
但是,实际情况是,在WINDOWS95和WINDOWS98平台下,   这样调用根本就无法连接上库文件.真正的API声明应该是:   
DWORD   NetSessionEnum(   LPSTR,    
DWORD,    
LPBYTE,    
DWORD,    
LPDWORD,    
LPDWORD   )    
参数1:   NULL表示枚举本机的网络连接    
参数2:   不详.在枚举中是常量0x32.    
参数3:   存放信息的缓冲区指针    
参数4:   缓冲区长度    
参数5:   指向返回连接个数    
参数6:   指向总共连接个数    
可见,参数个数完全不同,另外参数意义也发生了变化.       
2.依次断开枚举出的网络连接:    
还算幸运的是,断开网络连接的API声明是正确的:    
NET_API_STATUS   NetSessionDel(    
LPWSTR   servername,      
LPWSTR   UncClientName,      
LPWSTR   username   );    
不过要注意的是,第2个和第3个参数的内容需要    
从枚举得到的缓冲区中去取.具体方法参见程序.       
四.源代码:       
以下是实现断开网络连接的子程序,你可以方便的把它们加入到自己的项目中    
去,而不用和我一样浪费时间去研究到底怎样实现网络枚举了.       
注:由于本程序只实际用到了一个SVRAPI.DLL中的函数声明,简便期间,我没有    
用原有的头文件,自己定义一下就可以了.  
///////////////////////////////////////////////////////////////////    
//   File:   NetClose.H    
//   Version:   1.01    
     
#define   NETBUFF_SIZE   0x208    
     
#define   NetSessionEnum_PROFILE   (   DWORD   (__stdcall   *)   (   LPSTR,   DWORD,   LPBYTE,   DWORD,   LPDWORD,   LPDWORD   )   )    
#define   NetSessionDel_PROFILE   (   DWORD   (__stdcall   *)   (   LPSTR,   LPSTR,   DWORD   )   )    
///////////////////////////////////////////////////////////////////    
//   File:   NetClose.CPP    
//   Version:   1.01    
///////////////////////////////////////////////////////////////////    
//   Define:   BOOL   NetCloseAll(   VOID   )    
//   Parameters:   None    
//   Return:   TRUE   or   FALSE    
//    
//   Author:   Mr.Huang   fei    
//   Time:   5/7/1998    
//   Note:   Can   only   be   used   on   Windows95   &   Windows98    
//   Remark:   Close   all   network   conneCTions    
///////////////////////////////////////////////////////////////////    
BOOL   NetCloseAll(   VOID   )    
{    
BYTE   byBuff[NETBUFF_SIZE];    
DWORD   dwNetRet   =   0;;    
DWORD   i   =   0;    
DWORD   dwEntries   =   0;    
DWORD   dwTotalEntries   =   0;    
LPSTR   szClient   =   NULL;    
DWORD   dwUserName   =   0;    
BOOL   bRet   =   FALSE;    
LPBYTE   lpbyBuff   =   (LPBYTE)byBuff;    
     
DWORD   (__stdcall   *   hookNetSessionEnum)(   LPSTR,   DWORD,   LPBYTE,   DWORD,   LPDWORD,   LPDWORD   );    
DWORD   (__stdcall   *   hookNetSessionDel)(   LPSTR,   LPSTR,   DWORD   );    
     
HINSTANCE   hMod   =   LoadLibrary(   "SVRAPI.DLL"   );    
if(   hMod   !=   NULL   )    
{    
//   Get   the   address   of   function    
hookNetSessionEnum   =   NetSessionEnum_PROFILE    
GetProcAddress    
(   hMod,   TEXT("NetSessionEnum")   );    
hookNetSessionDel   =   NetSessionDel_PROFILE    
GetProcAddress    
(   hMod,   TEXT("NetSessionDel")   );    
     
if(   (   hookNetSessionDel   !=   NULL   )   &&    
(   hookNetSessionEnum   !=   NULL   )   )    
{    
dwNetRet   =   hookNetSessionEnum(   NULL,    
0x32,   byBuff,    
NETBUFF_SIZE,   &dwEntries,    
&dwTotalEntries   );    
if(   dwNetRet   ==   0   )    
{    
bRet   =   TRUE;    
for(   i=0;   i   <   dwTotalEntries;   i++   )    
{    
szClient   =   (LPSTR)(((DWORD   *)    
lpbyBuff)[0]);    
dwUserName   =   ((DWORD   *)lpbyBuff)[2];    
dwNetRet   =   hookNetSessionDel(   NULL,    
szClient,   dwUserName   );    
if(   dwNetRet   !=   0   )    
{    
bRet   =   FALSE;    
break;    
}    
lpbyBuff   +=   26;    
}    
}   //   NetSessionEnum(...)    
else    
bRet   =   FALSE;    
}   //   GetProcAddress(...)    
else    
bRet   =   FALSE;    
     
FreeLibrary(   hMod   );    
}   //   LoadLibrary(...)    
return   bRet;    
}    
     
五.总结:    
怎么设置客户端自动连接服务器啊?  
现在要开发一个网络通讯客户端程序,用的是TCP/IP协议,具体的协议已经拟订好了。简单的描述及时每隔30秒客户端自动向服务器端传输一组数据。因为我的客户端机器要一天24小时不停的运行,而且是无人值守的,那万一网络中断或是服务器端关机等异常情况发生,导致连接中断时,我的客户端程序必须保证在服务器端启动后,客户端能自动连接上服务器。我现在不清楚该怎么设置connect函数,才能做到这一点。  
还有,对于这种程序,我该采用多线程阻塞模式好呢,还是采用非阻塞模式好些?对于我这一点,我始终都确定不了别人都是采取哪种方法实现的?  
如果我要在程序中发送心跳包的话,该怎么做呢?