免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 908 | 回复: 0
打印 上一主题 下一主题

创建能够超时的socket连结API [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-08-09 09:48 |只看该作者 |倒序浏览
在socket编程中调用connect函数连接一远程机器,如果该ip不存在的话,connect将在一段时间内返回-1表示失败。问题是有时候我们需要准确控制connect函数连接的时间,这就需要我们能够控制这个connect函数。但是,gcc给我们提供的API没有这个功能。我自己设计了一个这样的API函数--connect2,它能够在用户设置的一段时间后,连接超时退出。
      这个connect2的初步设计思想是利用多线程,创建一个独立的线程调用socket的connect函数去连接,这样这个线程就可以被杀掉。我们首先要根据用户的需求设立一个alarm,并设置好alarm到点之后的动作,那就是取消掉连接线程。如果在alarm到点之前这个线程已经返回那就返回连接成功,否则连接线程将被取消,也就说明连接在规定的时间内失败,函数返回失败。
      好了。设计思想比较简单。下面来看看实现。
//函数定义
int connect2(SOCKET sock,struct sockaddr * addr,int timeout)
//函数实现
/**This implementation is for LINUX
* @version 1.0
* @author Jerry Hou
*/
#include
#include
#include
#include
#include
#include
#include "connect_timeout.h"
int g_sock;
pthread_t connect_thread;
void *sock_connect(void * argv);
void sock_cancel(int no);
int connect2(SOCKET sock,struct sockaddr * addr,int timeout)
{
        int res;
        struct sigaction act;
        g_sock=sock;
        res=pthread_create(&connect_thread,NULL,sock_connect,(void *)addr);
        if(res!=0)
                return errno;
        act.sa_handler=sock_cancel;
        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        if(sigaction(SIGALRM,&act,NULL)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这个connect2 API能够较准确在规定时间内TIMEOUT,但是还有一些问题。先不说了,改天有空再说。希望有人捧场。
     接着上面的讨论。细心的朋友会发现这个connect2函数的问题,那就是它只能允许在一个connect2调用完才能进行第二个调用,否则另外一个调用会影响到前面的调用。也就是说,只能在单线程中使用,不是线程安全(thread-safe)或可重入的(reentrant)。
     造成这个原因一是设计中我们调用了alarm这个gcc库的api,而它是进程范围的,也就是说后边alarm设置会影响到前面的设置。二是我们使用了2个全局变量,这样后边的connect2调用会改写这2个变量影响到前面的调用。
     解决的办法是我们需要一个线程安全的定时器timer,无论哪个定时器的设置都不会影响到其他的定时器工作。理想的这样一个timer函数应该是这样定义的:
int timer(int seconds,(void)ontimer(void * agrv) ,void *argv); 其中,seconds是超时时间,timerfunc是超时要执行的函数地址,argv是传入该函数的参数。好,我们假设有了这样一个线程安全的timer,我们来重写connect2。timer的实现我放在另外一篇文章里单独介绍,因为它不仅可以用在这里。
/**This implementation is for LINUX
* @version 1.1
* @author Jerry Hou
*/
#include
#include
#include
#include
#include
#include "timer.h"  //header file containing definitions of timer related APIs
#include "connect_timeout.h"
void * sock_connect(void * argv);
void  sock_cancel(void * argv);
int connect2(SOCKET sock,struct sockaddr * addr,int timeout)
{
        int res;
        pthread_t connect_thread;
        res=pthread_create(&connect_thread,NULL,sock_connect,(void *)addr);
        if(res!=0)
                return errno;
        res=timer(timeout,socke_cancel,(void *)&connect_thread);
        if(res!=0)
                return res;
        int * pres=NULL;
        res=pthread_join(connect_thread,(void **)&pres);
        if(res!=0)
                return errno;
        if(pres!=NULL)
        if(pres==PTHREAD_CANCELED)
                return -1;
        return *pres;
  
}
void * sock_connect(void * argv)
{
        struct sockaddr * s_addr=(struct sockaddr *)argv;
        int *pres=(int *)malloc(sizeof(int));
        int res=connect(g_sock,s_addr,sizeof(struct sockaddr_in));
        *pres=res;
        pthread_exit(pres);
}
void  sock_cancel(void * argv)
{
        pthead_t *pthread=(pthead_t *)argv;
        pthread_cancel(pthread);
//      timeout=1;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/8993/showart_39783.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP