- 论坛徽章:
- 4
|
回复 #4 zhaocong94005 的帖子
因为你的代码中的recv和send调用都是堵塞方式的,接收或发送时应使用select或poll并设置超时(timeout)。你可以调用如下的函数来接收数据包:
int tcprecvdata(int sock,void* data,int size,int timeout)
{
int byteleft;
int result;
unsigned char* p;
fd_set read_set;
fd_set exception_set;
struct timeval t;
if(data==NULL)
{
#ifdef __DEBUG__
fprintf(stderr,"%s,%d:tcprecvdata argument data is NULL.\n",
__FILE__,__LINE__);
#endif
return(-1);
}
p=(unsigned char*)data;
byteleft=size;
FD_ZERO(&read_set);
FD_ZERO(&exception_set);
while(byteleft>0)
{
FD_CLR(sock,&read_set);
FD_CLR(sock,&exception_set);
FD_SET(sock,&read_set);
FD_SET(sock,&exception_set);
if(timeout <= 0)
{
result=select(sock+1,&read_set,NULL,&exception_set,NULL);
}
else
{
t.tv_usec = 0;
t.tv_sec = timeout;
result=select(sock+1,&read_set,NULL,&exception_set,&t);
}
if(result<0)
{
#ifdef __DEBUG__
fprintf(stderr,"%s,%d:tcprecvdata call select failed:%s.\n",
__FILE__,__LINE__,strerror(errno));
#endif
return(-1);
}
else if(result==0)
{
#ifdef __DEBUG__
fprintf(stderr,"%s,%d:tcprecvdata call select timeout.\n",
__FILE__,__LINE__);
#endif
return(0);
}
if(FD_ISSET(sock, &read_set))
{
result=read(sock,p,byteleft);
if(result<0)
{
#ifdef __DEBUG__
fprintf(stderr,"%s,%d:tcprecvdata call read failed:%s.\n",
__FILE__,__LINE__,strerror(errno));
#endif
return(-1);
}
if(result == 0)
{
#ifdef __DEBUG__
fprintf(stderr, "%s,%d:tcprecvdata call read return 0, remote close connection? errno:%d, error info:%s.\n",
__FILE__, __LINE__, errno, strerror(errno));
#endif
return(-1);
}
byteleft-=result;
p+=result;
continue;
}
/*exception not support*/
return(-1);
}
return(1);
} |
|