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

转载于:https://my.oschina.net/u/211101/blog/36721

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值