在現(xiàn)代的互聯(lián)網(wǎng)硬件TCP連接connect等待時長控制的另一種方法環(huán)境中,一分鐘的等待有點太長了,我們需要縮短等待時間。
在Linux環(huán)境下,可以用alarm調(diào)用定時喚醒正在等待的線程,使connect函數(shù)從等待中返回,但在Windows下我沒有找到類似的函數(shù)。如何讓connect函數(shù)返回呢?
經(jīng)過實驗,找到一個簡單的方法:直接關(guān)閉connect函數(shù)使用的那個socket套接字,connect函數(shù)就會立即返回。這個方法感覺土了點,但確實管用。該方法的工作過程描述如下:
1) 創(chuàng)建socket
2) 啟動定時關(guān)閉該socket的線程
3) 調(diào)用connect函數(shù)連接服務(wù)器
4) 取消定時關(guān)閉線程的工作
5) 檢查定時關(guān)閉線程的關(guān)閉操作是否已經(jīng)執(zhí)行
6) 檢查connect返回值是否有效
摘錄一段示例代碼如下:
SOCKET CTCPConnector::ConnectTo(
int toIp, int toPort,
int localIp , int localPort,
int timeOut)
{
SOCKET Socket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in InetAddr;
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(localIp);
InetAddr.sin_port = htons(localPort);
if (localIp > 0 && localPort>0)
{
if (bind(Socket, (sockaddr *) &InetAddr, sizeof(InetAddr)) < 0)
return INVALID_SOCKET;
}
InetAddr.sin_addr.s_addr= htonl(toIp);
InetAddr.sin_port = htons(toPort);
CTimeOutClose Closer(Socket); //這個是超時關(guān)閉線程
if (timeOut > 0)
Closer.SetTimeOut(timeOut);// 設(shè)定超時時長
int err = connect(Socket, (const sockaddr *)&InetAddr, sizeof(InetAddr));
if (timeOut >= 0)
{
Closer.Cancel();//取消超時關(guān)閉
if (Closer.HasDone()//檢查定時關(guān)閉線程的關(guān)閉操作是否已經(jīng)執(zhí)行
&& err >= 0) //
{
err = -1; }
}
if ( err < 0) //檢查connect返回值是否有效
{ return INVALID_SOCKET;
}
return Socket;
}
代碼中CTimeOutClose類是啟動關(guān)閉線程,等待一段時間后關(guān)閉指定的套接字。同時,該類還提供接口,用于取消操作和檢查操作是否已經(jīng)執(zhí)行。
雖然該方法需要啟動一個新的線程,但對于大多數(shù)的應(yīng)用來說,主動發(fā)起建立TCP連接的量都不會太多,所以對程序的性能并不會產(chǎn)生明顯影響。
(以上代碼可以在我上傳的資源“回城卷軸網(wǎng)絡(luò)通訊架構(gòu)源代碼”中找到,下載地址為:http://download.csdn.net/source/1023342)
作者:蘇林