|
|
[size=18:ac54d21053]在客户端与服务器端通过socket连接时,有两个问题必须考虑
1、connect连接时可能会发生连接不上的情况,需要实现超时退出程序。
2、连接后在接收数据的过程中,可能发生网络中断,不能接受数据的情况,需要退出程序。
这两个问题应该很常见,希望高手给大家详细地讲解一下,谢谢。[/size:ac54d21053]
| gadfly 回复于:2003-08-11 14:40:32
| 这两个都可以用非阻塞socket,select控制超时
| | yuanyawei 回复于:2003-08-12 09:08:00
| 我觉得第一种情况用select可以很好解决。
但第二种情况在遇到客户端直接拔网线的情况时,server端的情况较难判断,要看内核的参数,linux下较好处理,BSD也没问题,HP和AIX也能处理,但SCO下就不好办了(参数老调不好)。
| | minsky 回复于:2003-08-12 10:52:27
| 1.connect超时:
1)setsockopt();//将socket置为非阻塞模式;
2)connect();
3)判断connect()的返回值,一般情况会返回-1,这时你还必须判断错误码如果是EINPROGRESS,那说明connect还在继续;如果错误码不是前者那么就是有问题了,不必往下执行,必须关掉socket;待下次重联;
4)select();设置好函数中的超时时间,将select()中的read和write项置上,在超时时间内,如果select返回1,即描述字变为了可写,那么连接成功;如果返回2,即描述字变为即可读又可写,那么出错;如果返回0,那么超时;
============================================
2.网络中断:
如果你的程序是客户端.用select检查描述符的状态,如果可读就recv(),根据recv()的返回值来判断网络情况;
| | calfen 回复于:2003-12-18 15:18:55
| unp上明确说setsockopt只能用在读写时候不能用在connect上啊...
| | grouploo 回复于:2004-06-25 23:06:35
| /********************************************/
/**** 作者::夕君 **/
/**** 时间:2004.04.04 **/
/**** 北京金万维科技 http://www.gnway.com **/
/*******************************************/
/*此函数实现判断m_server的m_port端口是否可以连上,超时限制为nTimeOut秒*/
BOOL ConnectTest(char * m_server,int m_port)
{
struct hostent* host = NULL;
struct sockaddr_in saddr;
unsigned int s = 0;
BOOL ret;
time_t start;
int error;
host = gethostbyname (m_server);
if (host==NULL)return FALSE;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(m_port);
saddr.sin_addr = *((struct in_addr*)host->h_addr);
if( (s=socket(AF_INET, SOCK_STREAM, 0))<0){
return FALSE;
}
fcntl(s,F_SETFL, O_NONBLOCK);
if(connect(s,(struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
if (errno == EINPROGRESS){// it is in the connect process
struct timeval tv;
fd_set writefds;
tv.tv_sec = m_nTimeOut;
tv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
if(select(s+1,NULL,&writefds,NULL,&tv)>0){
int len=sizeof(int);
//下面的一句一定要,主要针对防火墙
getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len);
if(error==0) ret=TRUE;
else ret=FALSE;
}else ret=FALSE;//timeout or error happen
}else ret=FALSE;
}
else ret=TRUE;
close(s);
return ret;
}
| |
|