免费注册 查看新帖 |

Chinaunix

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

请熟悉SOCKET的朋友看看这函数。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-05 01:20 |只看该作者 |倒序浏览
  1. 这个程序里面用了2个套接字,一个本地套接字,一个监听外部连接时的套接字。
  2. 主要不清楚这个本地套接字有什么用,因为觉得哪个监听外部的完全都可以了,大家能解释解释本地套接字作用吗?谢谢了
  3. int     main(int argc, char *argv[])
  4. {
  5.     char        szFile[256], szServicesName[64], szIP[32], szLine[257];
  6.     long        lPid, lPort, lRet;
  7. #ifdef  IBM_AIX
  8.     unsigned long   iLen;
  9. #else
  10.     int         iLen;
  11. #endif
  12.     int         skMax, skNew, skLocal, skExtern, skServer;
  13.     fd_set      rset, setsave;
  14.     struct      _ALSend
  15.     {
  16.         long    lPort;
  17.         struct  sockaddr_in saClient;
  18.     }stSend;

  19.     logv_SetFile(TCSERV_LOGFILE);
  20.     /*  初始化*/
  21.     if(tcomml_InitDaemon() != RC_SUCCESS)
  22.     {
  23.         Trace("初始化驻留进程失败!");
  24.         fprintf(stdout, "启动tcserv失败!");
  25.         exit(RC_FAILURE);
  26.     }

  27.     /*  得到本进程的监听端口*/
  28.     lPort = tcomml_GetListenPort();
  29.     if(0 >= lPort)
  30.     {
  31.         printf("tcserv:load listen port Error!\n"); fflush(stdout);
  32.         exit(RC_FAILURE);
  33.     }

  34.     /*  获取交易信息配置*/
  35.     lRet = tcomml_LoadTrConfig();
  36.     if(lRet == RC_FAILURE)
  37.     {
  38.         printf("tcserv:load trConfig Error!\n"); fflush(stdout);
  39.         exit(RC_FAILURE);
  40.     }
  41.     else
  42.         g_lCurTrCount = lRet;

  43.     FD_ZERO(&setsave);
  44.     skExtern = socki_BindExtern(lPort, 5);        /*******这个函数作用是用指定端口监听外部连接,后面贴有函数******/
  45.     if(RC_FAILURE == skExtern)
  46.     {
  47.         Trace("绑定本地端口出错!");
  48.         exit(RC_FAILURE);
  49.     }
  50.     skMax = skExtern;
  51.     FD_SET(skExtern, &setsave);

  52.     /*  产生一个本地监听用的套节子接口*/
  53.     if((skLocal = socki_BindLocal()) == RC_FAILURE) /******这个是产生的本地套接字,是用SOCKET文件的形式。这个做什么用?后面贴有函数*****/
  54.     {
  55.         Trace("产生本地套节子失败");
  56.         close(skExtern);
  57.         exit(RC_FAILURE);
  58.     }
  59.     if(skLocal > skMax)
  60.         skMax = skLocal;

  61.     FD_SET(skLocal, &setsave);

  62.     while(1)
  63.     {
  64.         rset = setsave;
  65.         select(skMax + 1, &rset, NULL, NULL, NULL);
  66.         if(FD_ISSET(skLocal, &rset))    [color=Red]/******主要是不清楚这个if分支的作用,因为感觉下面的if分支都完全可以处理****/[/color]
  67.         {
  68.             /*  一个本地的请求一定是监测进程*/
  69.             Trace("收到本地的请求!");
  70.             iLen = sizeof(stSend.saClient);
  71.             memset(&stSend, 0, sizeof(struct _ALSend));
  72.             lRet = recvfrom(skLocal, szLine, 256, 0,
  73.                     (struct sockaddr*)&stSend.saClient, &iLen);
  74.             if(0 <= lRet)
  75.             {
  76.                 Tstring(lRet, szLine);
  77.             }
  78.             continue;
  79.         }
  80.         if(FD_ISSET(skExtern, &rset))
  81.         {
  82.             iLen = sizeof(stSend.saClient);
  83.             memset(&stSend, 0, sizeof(struct _ALSend));
  84.             skNew = accept(skExtern, (struct sockaddr*)&stSend.saClient, &iLen);
  85.             if(skNew < 0)
  86.             {
  87.                 Trace("Accept Extern Error!");
  88.                 continue;
  89.             }
  90.             /*  将得到的IP地址转换为字符串*/
  91.             memset(szIP, 0, sizeof(szIP));
  92.             strcpy(szIP, (char*)inet_ntoa(stSend.saClient.sin_addr));
  93. Trace("收到来自地址%s的请求", szIP);

  94.             memset(szServicesName, 0, sizeof(szServicesName));
  95.             if(socki_Auth(skNew, szServicesName, szIP) == RC_FAILURE)
  96.             {
  97.                 close(skNew);
  98.                 Trace("系统认证失败,非法授权用户连接!");
  99.                 continue;
  100.             }
  101. Trace("通过认证");

  102.             if(0 >= (lPid = tcomml_SelectServer(szServicesName)))        /*这个函数作用是选择可用的服务进程*/
  103.             {
  104.                 close(skNew);
  105.                 Trace("系统忙,无可用的服务进程!");
  106.                 continue;
  107.             }

  108.             /*  写出套节子,需要将端口号和客户端信息同时传递过去*/
  109.             iLen = sizeof(stSend);
  110.             stSend.lPort = lPort;

  111. Trace("连接进程(%d)", lPid);
  112.             if((skServer = socki_ConnectLocal(lPid)) < 0)        /*****用socket文件的形式,连接刚才的可用服务进程,后面贴有函数****/
  113.             {
  114.                 Trace("连接进程(%d)出错", lPid);
  115.                 close(skNew);
  116.                 continue;
  117.             }
  118.             if(RC_SUCCESS != socki_Writefd(skServer, &stSend, iLen, skNew))        /****是向可用的服务进程发送数据*****/
  119.             {
  120.                 Trace("通过(%d)发送套节子(%d)失败", skServer, skNew);
  121.             }
  122.             close(skNew);
  123.             close(skServer);
  124.             continue;
  125.         }
  126.     }
  127. }
复制代码

[ 本帖最后由 ablised 于 2009-4-5 01:24 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-04-05 01:21 |只看该作者
/******************************************************************************
&nbsp;&nbsp;&nbsp;&nbsp;函 数 名:socki_BindExtern          函数编号:
&nbsp;&nbsp;&nbsp;&nbsp;功能描述:建立一个AF_INET的套节子,绑定到指定的端口并设置监听队列深度
&nbsp;&nbsp;&nbsp;&nbsp;入口参数:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in_lPort            --端口号
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in_lQueue           --设置监听队列的深度
&nbsp;&nbsp;&nbsp;&nbsp;返回说明:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;>0                  --返回得到的套节子
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RC_FAILURE          --失败
&nbsp;&nbsp;&nbsp;&nbsp;引用变量:
&nbsp;&nbsp;&nbsp;&nbsp;开发历史:
&nbsp;******************************************************************************/

int     socki_BindExtern(long in_lPort, long in_lQueue)
{
&nbsp;&nbsp;&nbsp;&nbsp;long    lRet;
&nbsp;&nbsp;&nbsp;&nbsp;int     iLen, sockfd, iSockCtl;
&nbsp;&nbsp;&nbsp;&nbsp;struct  sockaddr_in stAddr;

&nbsp;&nbsp;&nbsp;&nbsp;sockfd = socket(AF_INET, SOCK_STREAM, 0);
&nbsp;&nbsp;&nbsp;&nbsp;if(0 > sockfd)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("generate socket error");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;iLen = sizeof(iSockCtl);
&nbsp;&nbsp;&nbsp;&nbsp;iSockCtl = 1;
&nbsp;&nbsp;&nbsp;&nbsp;lRet = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&iSockCtl, iLen);
&nbsp;&nbsp;&nbsp;&nbsp;if(-1 == lRet)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("set socket REUSEADDR error");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;stAddr.sin_family = AF_INET;
&nbsp;&nbsp;&nbsp;&nbsp;stAddr.sin_addr.s_addr = htonl(INADDR_ANY);
&nbsp;&nbsp;&nbsp;&nbsp;stAddr.sin_port = htons(in_lPort);
&nbsp;&nbsp;&nbsp;&nbsp;lRet = bind(sockfd, (struct sockaddr*)&stAddr, sizeof(stAddr));
&nbsp;&nbsp;&nbsp;&nbsp;if(0 > lRet)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("Bind port %d error", in_lPort);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;/*  设置可以监听的最大的数量*/
&nbsp;&nbsp;&nbsp;&nbsp;if(listen(sockfd, in_lQueue) < 0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("listen on socket %d error", sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return sockfd;
}

论坛徽章:
0
3 [报告]
发表于 2009-04-05 01:22 |只看该作者

/******************************************************************************
&nbsp;&nbsp;&nbsp;&nbsp;函 数 名:socki_BindLocal           函数编号:
&nbsp;&nbsp;&nbsp;&nbsp;功能描述:建立一个AF_LOCAL式的套节子,并绑定到指定的文件名
&nbsp;&nbsp;&nbsp;&nbsp;入口参数:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in_pszFile          --指定的文件名
&nbsp;&nbsp;&nbsp;&nbsp;返回说明:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;>0                  --返回得到的套节子
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RC_FAILURE          --失败
&nbsp;&nbsp;&nbsp;&nbsp;引用变量:
&nbsp;&nbsp;&nbsp;&nbsp;开发历史:
&nbsp;******************************************************************************/

int     socki_BindLocal()
{
&nbsp;&nbsp;&nbsp;&nbsp;char    szFile[256];
&nbsp;&nbsp;&nbsp;&nbsp;int     iRet, sockfd;
&nbsp;&nbsp;&nbsp;&nbsp;struct  sockaddr_un servaddr;

&nbsp;&nbsp;&nbsp;&nbsp;memset(szFile, 0, sizeof(szFile));
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(szFile, "%s/bin/.tclocal.%d", getenv("TCHOME"), getpid());
&nbsp;&nbsp;&nbsp;&nbsp;unlink(szFile);                 /*  防止文件已经存在*/
&nbsp;&nbsp;&nbsp;&nbsp;sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
&nbsp;&nbsp;&nbsp;&nbsp;memset(&servaddr, 0, sizeof(servaddr));
&nbsp;&nbsp;&nbsp;&nbsp;servaddr.sun_family = AF_LOCAL;
&nbsp;&nbsp;&nbsp;&nbsp;strncpy(servaddr.sun_path, szFile, sizeof(servaddr.sun_path) - 1);
&nbsp;&nbsp;&nbsp;&nbsp;iRet = bind(sockfd, (struct sockaddr*)&servaddr, SUN_LEN(&servaddr));
&nbsp;&nbsp;&nbsp;&nbsp;if(0 != iRet)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("bind socket on %s error", szFile);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return sockfd;
}


/******************************************************************************
&nbsp;&nbsp;&nbsp;&nbsp;函 数 名:socki_ConnectLocal        函数编号:
&nbsp;&nbsp;&nbsp;&nbsp;功能描述:连接到一个指定文件名的本地套节子
&nbsp;&nbsp;&nbsp;&nbsp;入口参数:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in_pszFile          --指定的文件名
&nbsp;&nbsp;&nbsp;&nbsp;返回说明:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;>0                  --返回得到的套节子
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RC_FAILURE          --失败
&nbsp;&nbsp;&nbsp;&nbsp;引用变量:
&nbsp;&nbsp;&nbsp;&nbsp;开发历史:
&nbsp;******************************************************************************/

int     socki_ConnectLocal(long in_lPid)
{
&nbsp;&nbsp;&nbsp;&nbsp;char    szFile[256];
&nbsp;&nbsp;&nbsp;&nbsp;int     iRet, sockfd;
&nbsp;&nbsp;&nbsp;&nbsp;struct  sockaddr_un cliaddr;

&nbsp;&nbsp;&nbsp;&nbsp;memset(szFile, 0, sizeof(szFile));
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(szFile, "%s/bin/.tclocal.%d", getenv("TCHOME"), in_lPid);
&nbsp;&nbsp;&nbsp;&nbsp;sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
&nbsp;&nbsp;&nbsp;&nbsp;memset(&cliaddr, 0, sizeof(cliaddr));
&nbsp;&nbsp;&nbsp;&nbsp;cliaddr.sun_family  = AF_LOCAL;
&nbsp;&nbsp;&nbsp;&nbsp;strncpy(cliaddr.sun_path, szFile, sizeof(cliaddr.sun_path) - 1);
&nbsp;&nbsp;&nbsp;&nbsp;iRet = connect(sockfd, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
&nbsp;&nbsp;&nbsp;&nbsp;if(0 != iRet)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Trace("connect to socket %d error", sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return RC_FAILURE;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return sockfd;
}

论坛徽章:
0
4 [报告]
发表于 2009-04-05 15:55 |只看该作者
没人能讲讲吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP