TCP断线自动重连

wade008 2010-03-25 08:55:08
Server把IP和Port绑定后, Client通过对应的IP和Port去connect, 连上了


如果过一段时间,断线了,那Server的Port就被占用了,server就得重新指定个Port,然后Client才能连上


可是这就不是自动重连,而是手动重连


现在想要做的是,当断线时, Client能自动连上,这要如何做呢?
...全文
2462 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
houwen88062601 2011-12-15
  • 打赏
  • 举报
回复
楼主能不能把你的这个源码发给我,谢谢,296886815@qq.com
Jack__h 2011-09-22
  • 打赏
  • 举报
回复
void CScanagentTestDlg::AcceptThread(LPVOID lParam)
{
CScanagentTestDlg *pDlg = (CScanagentTestDlg*)lParam;
SOCKADDR_IN addrClient;
int nLen = sizeof(SOCKADDR);

if (listen(pDlg->m_hSocketConn, 1) == SOCKET_ERROR)
{
closesocket(pDlg->m_hSocketConn);
pDlg->m_hSocketConn = INVALID_SOCKET;
return;
}

while(pDlg->m_bAccept)
{
//AfxMessageBox(L"Listen");
Sleep(100);

if(pDlg->m_hSocketServer == INVALID_SOCKET)
pDlg->m_hSocketServer = accept(pDlg->m_hSocketConn, (SOCKADDR*)&addrClient, &nLen);

//pDlg->m_bAccept = FALSE;
}
}
笨笨仔 2010-03-25
  • 打赏
  • 举报
回复
我的一个试验结果小结,供参考。
关于异步网络通信的实验结果

客户端
1. 连接(Connect):连接指令发出后,会立即返回一个错误码,该值只描述了程序执行的正确与否,比如程序流程不正确等;而OnConnect事件才可以正确返回实际的网络连接状态。该事件的返回错误码=0时,表示连接正常,之后会收到OnSend事件;如果连接错误,返回错误码=错误代码,并回到原状态。
2. 发送(Send):正常发送指令发出后,会立即返回一个错误码,该值只描述发送程序执行的正确与否,比如参数错误等;而OnSend事件才可能正确返回实际发送状态,该事件的返回错误码=0时,表示发送正常,并回到原状态;如果出现错误,返回错误码=错误代码,并回到原状态。
3. 网络断开(Close):网络连接可使用Close指令控制断开,也可以通过切断网络或关闭服务源强行断开。网络断开后,会收到OnClose事件,在网络断开到收到OnClose事件之间有一个时间差,约3~5秒,在这之间如果使用Send发送,将收不到OnSend事件,而只会收到OnClose事件。服务端正常断开,nErrorCode返回0,非正常断开时,返回一个错误代码。
4. 接收到OnReceive事件:表示有数据需要接收,该事件返回一个错误码,当返回错误码=0时,可以使用Receive指令接收,该指令返回实际收到的字节数。
5. 断开连接(Close):执行Close指令,可断开网络。

服务端
在堆中创建套接字(使用New Socket)
1. 服务端开始3步曲:初始化套接字、创建套接字、建立侦听。
2. 使用API函数初始化套接字,再用Create进行创建,该套接字为的是侦听;创建成功使用Listen打开侦听。以上三个过程中,如果成功均返回TRUE,失败则返回FALSE。
3. 收到客户接收事件(OnAccept):表示与客户端连接成功。这时需要建立一个新的套接字,作为与客户端通信数据之用,并使用Accept指令代新建的套接字响应客户端,该指令返回一个布尔值,如果响应成功返回TRUE,否则返回FALSE。而最初创建的套接字,只用于网络侦听,因而可建立多个连接。
4. 一但与客户端建立了联系,通信与响应方式与上面的客户端相同。

具体操作时,服务端在网络断开后,丢掉老的Socket,继续侦听;客户端在网络断开后(自己判断),执行重新连接。可见,自动连接的关键在客户端,而不在服务端。
这不是鸭头 2010-03-25
  • 打赏
  • 举报
回复
心跳的作用是维护连通性和判断是否有如直接拔掉网线这样的断线的....
估计你的服务监听部分有问题。
不知道你用的什么模型。应该不会和端口的关系。
这不是鸭头 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用楼主 wade008 的回复:]
Server把IP和Port绑定后, Client通过对应的IP和Port去connect, 连上了


如果过一段时间,断线了,那Server的Port就被占用了,server就得重新指定个Port,然后Client才能连上


可是这就不是自动重连,而是手动重连


现在想要做的是,当断线时, Client能自动连上,这要如何做呢?
[/Quote]
不太可能出现这样问题吧?
如果是这样的话,服务器是不是只能连入一个客户端?
wade008 2010-03-25
  • 打赏
  • 举报
回复
高手呢?
wade008 2010-03-25
  • 打赏
  • 举报
回复
2. server 端口改变,那只自己从[1, 65535]个端口里,依次去尝试连接。

如果用原来的端口,client显示连上了,可是server好像没有连上
icefairy 2010-03-25
  • 打赏
  • 举报
回复
mark mark
wade008 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wenxy1 的回复:]
1. 自动重连,用心跳包做检测。
2. server 端口改变,那只自己从[1, 65535]个端口里,依次去尝试连接。
[/Quote]
server重新监听时,端口会改变了?
Wenxy1 2010-03-25
  • 打赏
  • 举报
回复
1. 自动重连,用心跳包做检测。
2. server 端口改变,那只自己从[1, 65535]个端口里,依次去尝试连接。
wade008 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bragi523 的回复:]
server端心跳检测链接,断开后立即关闭socket,然后重新监听?
[/Quote]

立即关闭,然后重新监听,这样可以吗?

我现在没有用心跳包来做,只是手动去断掉,然后关闭socket,再重新监听,可是连不上
bragi523 2010-03-25
  • 打赏
  • 举报
回复
server端心跳检测链接,断开后立即关闭socket,然后重新监听?
wade008 2010-03-25
  • 打赏
  • 举报
回复
第一次知道以后,用同个Port有没有办法再让连上?
ouyh12345 2010-03-25
  • 打赏
  • 举报
回复
client得知道server的端口吧,不然怎么连啊
wade008 2010-03-25
  • 打赏
  • 举报
回复
谢谢,你们的回复,问题解决了
wade008 2010-03-25
  • 打赏
  • 举报
回复
arpnet99

先谢谢你, 以上代码,麻烦你帮我看下,错在哪
wade008 2010-03-25
  • 打赏
  • 举报
回复

m_hSocketConn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_hSocketConn == INVALID_SOCKET)
{
m_hSocketConn = NULL;
return FALSE;
}

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(nPort);

if (bind(m_hSocketConn, (SOCKADDR*) &addrSrv, sizeof(addrSrv)) == SOCKET_ERROR)
{
closesocket(m_hSocketConn);
m_hSocketConn = INVALID_SOCKET;
return FALSE;
}

m_hAccept = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AcceptThread, this, 0, NULL);
m_bAccept = TRUE;


void CScanagentTestDlg::AcceptThread(LPVOID lParam)
{
CScanagentTestDlg *pDlg = (CScanagentTestDlg*)lParam;
SOCKADDR_IN addrClient;
int nLen = sizeof(SOCKADDR);

while(pDlg->m_bAccept)
{
//AfxMessageBox(L"Listen");
Sleep(100);
if (listen(pDlg->m_hSocketConn, 1) == SOCKET_ERROR)
{
closesocket(pDlg->m_hSocketConn);
pDlg->m_hSocketConn = INVALID_SOCKET;
return;
}

if(pDlg->m_hSocketServer == INVALID_SOCKET)
pDlg->m_hSocketServer = accept(pDlg->m_hSocketConn, (SOCKADDR*)&addrClient, &nLen);

//pDlg->m_bAccept = FALSE;
}
}

接到断线做如下:
closesocket(pDlg->m_hSocketServer);
pDlg->m_hSocketServer = INVALID_SOCKET;
这不是鸭头 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 wade008 的回复:]
引用 15 楼 arpnet99 的回复:
引用 13 楼 wade008 的回复:
引用 11 楼 arpnet99 的回复:
心跳的作用是维护连通性和判断是否有如直接拔掉网线这样的断线的....
估计你的服务监听部分有问题。
不知道你用的什么模型。应该不会和端口的关系。


我用的同步的, 用个Thread在监听,如果监听到了,就accept
感觉是你的监听部分的问题。

……
[/Quote]
你至少贴个代码吧,这样靠猜,不大好吧...
这不是鸭头 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 wade008 的回复:]
引用 15 楼 arpnet99 的回复:
引用 13 楼 wade008 的回复:
引用 11 楼 arpnet99 的回复:
心跳的作用是维护连通性和判断是否有如直接拔掉网线这样的断线的....
估计你的服务监听部分有问题。
不知道你用的什么模型。应该不会和端口的关系。


我用的同步的, 用个Thread在监听,如果监听到了,就accept
感觉是你的监听部分的问题。

……
[/Quote]
你至少贴个代码吧,这样靠猜,不大好吧...
wade008 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 arpnet99 的回复:]
引用 13 楼 wade008 的回复:
引用 11 楼 arpnet99 的回复:
心跳的作用是维护连通性和判断是否有如直接拔掉网线这样的断线的....
估计你的服务监听部分有问题。
不知道你用的什么模型。应该不会和端口的关系。


我用的同步的, 用个Thread在监听,如果监听到了,就accept
感觉是你的监听部分的问题。
[/Quote]

是监听存在问题,但是我关闭了,accept的socket,然后重新accept,好像不行
加载更多回复(5)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧