首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

TCP 连接超时有关问题

2012-12-15 
TCP 连接超时问题~前几天发了一个帖子, 今天发现问题依旧没解决TCP如果连接不上 将会一直阻塞在那 将近20

TCP 连接超时问题~
前几天发了一个帖子, 今天发现问题依旧没解决
TCP如果连接不上 将会一直阻塞在那 将近20秒的时间,让人难以忍受。
所以下面我写了下面的代码, 希望只要等待5秒就返回,可是失败了~~~ 求指点;主线程一定要阻塞着的,连接上以后才能有其他操作;
*.cpp:
BOOL CSelectModelDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE);// 设置大图标
SetIcon(m_hIcon, FALSE);// 设置小图标



WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 2);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
MessageBox(_T("初始化套接字库失败,将退出程序"));
return FALSE;
}

m_st = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_clientst == NULL )
{
MessageBox(_T("建立套接字失败"));
return FALSE;
}


sockaddr_in psaddr;
psaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
psaddr.sin_family = AF_INET;
psaddr.sin_port = htons(5555);

if(SOCKET_ERROR == ::bind(m_st,(sockaddr*)&psaddr,sizeof(psaddr)))
{
MessageBox(_T("绑定套接字失败"));
return FALSE;
}
if(SOCKET_ERROR == listen(m_st, 5))
{
MessageBox(_T("监听失败"));
return FALSE;
}




return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}


void CSelectModelDlg::OnBnClickedButton1()
{

m_clientst = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

CreateThread(NULL,0,ConnectProc,(LPVOID)m_clientst,0,NULL);


sockaddr_in psaddr;
psaddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.133");
psaddr.sin_family = AF_INET;
psaddr.sin_port = htons(5555);
if(SOCKET_ERROR == connect(m_clientst,(sockaddr *)&psaddr,sizeof(psaddr)))
{
AfxMessageBox("连接出错");
}

}
DWORD WINAPI CSelectModelDlg::ConnectProc(LPVOID lpParam)
{
SOCKET m_clientt = (SOCKET)lpParam;

struct   timeval   timeout; 
fd_set   fs;
FD_ZERO(&fs); 
FD_SET(m_clientt,&fs); 
timeout.tv_sec= 5; 
timeout.tv_usec= 0;

select(0,&fs,&fs,0,&timeout);

return 0;
}
*.h
public:
SOCKET m_st;
SOCKET m_clientst;

static DWORD WINAPI ConnectProc(LPVOID lpParam);
[最优解释]
 int iMode = 1; //0:阻塞
  ioctlsocket(socketc,FIONBIO, (u_long FAR*) &iMode);//非阻塞设置
[其他解释]
首先,主线程一定要阻塞着的,这种需求很费解
按照LZ的做法,开子线程是多余的,直接将select放主线程就搞定
[其他解释]
这个超时时间没法设置,是它内部有个算法。

但是你可以把socket设置成异步的,然后用select控制超时
------其他解决方案--------------------


[quote=
这样吗?[/quote]
ioctlsocket设置套接字为非阻塞模式
然后调用select
判断返回值是否为连接超时。
[其他解释]
你申请个线程,把主线程sleep 5秒了,看子线程是否有链接上。没连接上就返回。一般情况连接或者监听都要开线程的
[其他解释]

引用:
这个超时时间没法设置,是它内部有个算法。

但是你可以把socket设置成异步的,然后用select控制超时


怎么设置成异步, 是
while(1)
{
  select(....);
}
这样吗?
[其他解释]
不用while。

热点排行