免费注册 查看新帖 |

Chinaunix

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

sock 多进程问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-16 12:16 |只看该作者 |倒序浏览
本帖最后由 yp17 于 2010-04-16 12:19 编辑

服务端代码如下:
   
   msfd = socket( PF_INET, SOCK_STREAM, 0 );
    if ( msfd < 0 )   return(-1);

    memset( &svraddr, 0, sizeof(svraddr) );
    svraddr.sin_family = AF_INET;
    svraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    svraddr.sin_port = htons( port );

    if (setsockopt(msfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){
         return (-1);
    }

    if (bind(msfd,(struct sockaddr *)&svraddr,sizeof(svraddr)) < 0 ) {
        return(-1);
    }

    listen( msfd, lqlen );

    while (1) {
        ssfd = accept( msfd, cltip, &cltport);
        if ( ssfd == -1 ) {
            bflerrlog(E_ERRMSG,_FL_,"_sclsock_svraccept failed.\n");
            break;
        }

        switch ( fork() ) {
        case 0 :
           close(msfd);

           recv(s,pktptr,pktlen,0)) < 0 ) ;

           ×××××××××××××××
        一堆业务处理。。。
       ×××××××××××××××

       write( fd,ptr,maxn );

           close(ssfd);
           return(0);

       default :
            close(ssfd);
            break;
       case -1 :
            close(ssfd);
            return(1);
        }



出错情况如下:
1、第一次客户端发起请求,服务端程序卡在“业务处理”因为特殊原因卡死。
2、在服务端卡死的情况下再次发起导致服务器卡死的请求,服务端可以接受客户端请求,但运行到业务处理的地方卡住。
3、此时客户端发再起一个不会引起服务端卡死的请求,服务端可以正常处理完成并返回。
4、此时再发起任何请求,服务器均无响应,服务端程序停在recv处。。

请帮忙看看咋回事? 谢谢!

论坛徽章:
0
2 [报告]
发表于 2010-04-16 12:20 |只看该作者
  1.                                 memset(&sa, 0, sizeof(sa));   
  2.                                 socklen_t salen = sizeof(sa);   
  3.                                 int client = accept(_server_fd, (struct sockaddr *)&sa, &salen);
复制代码
类似这个

论坛徽章:
0
3 [报告]
发表于 2010-04-16 14:52 |只看该作者
本帖最后由 yp17 于 2010-04-16 15:04 编辑
类似这个
rain_fish 发表于 2010-04-16 12:20



此问题的关键在于多进程,举例如下:
客户端发送报文A 能导致服务端卡死。 发送报文B 则能正常运行完毕并返回。

如果客户端连续发送A 则服务端每件监听到一个A 就会开启一个子进程,子进程卡死,等待超时后退出。

如果客户端连续发送B 则服务端监听听到一个B 就会开启一个子进程并处理完成后正常返回给客户端,然后子进程退出。

现在情况是 客户端先发送A,在A还没有返回前(服务端卡死,未超时),如果再发送 B ,则第一次发送B的时候能正常返回。
然后无论发送 A还是发送B,服务端均无响应。必须等待接受到A报文的子进程超时退出后,才能恢复正常。


不好意思,是我偷懒了,事实上,accetp() 方法是封装了的。实现代码如下:
  1. int _sclsock_svraccept(int msfd,char *cltip,int *cltport)
  2. {
  3.     int  ssfd = 0;  struct sockaddr_in cltaddr;
  4.     int  addrlen = 0;   /* addr length */

  5.     addrlen = sizeof(cltaddr);
  6.     while (1) {
  7.         ssfd = accept( msfd,(struct sockaddr *)&cltaddr,&addrlen );

  8.         if ( ssfd < 0 ) {
  9.             if ( errno == EINTR )   continue;
  10.             return(-1);
  11.         }
  12.         strcpy( cltip, (char *)inet_ntoa(cltaddr.sin_addr) );
  13.         *cltport = ntohs(cltaddr.sin_port);
  14.         break;
  15.     }
  16.     return(ssfd);
  17. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP