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

基于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函数,才能做到这一点。   
还有,对于这种程序,我该采用多线程阻塞模式好呢,还是采用非阻塞模式好些?对于我这一点,我始终都确定不了别人都是采取哪种方法实现的?   
如果我要在程序中发送心跳包的话,该怎么做呢?

你可能感兴趣的:(基于TCP的socket编程网络掉线重连)