文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>09-7-7(2)

09-7-7(2)

时间:2009-07-07  来源:zlm8715

   在TCP服务中,如果服务器主机崩溃或者崩溃后重启,如果恰好一直与客户机没有数据交换,则客户机该如何去发现服务器的情况?    通过设置socket的SO_KEEPALIVE属性可解决该问题。
int nkeepalive=SO_KEEPALIVE;
setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(char *)nkeepalive,sizeof(int));  
                        //检测对方主机是否崩溃(即使客户机没有发数据给服务器),
                        //当服务器崩溃后又重启,客户机也能检测到,若没数据交换,
                        //每2小时发送一个驳斥存活探测分节(keepalive probe),
                        //避免(服务器)永远阻塞于TCP连接的输入

下面是关于send(),recv()函数的标志设置的一个实例说明:
客户端:
int opt=1000;                 
    setsockopt(sockfd,SOL_SOCKET,SO_SNDTIMEO,(char *)&opt,sizeof(int));   
                                      //设置发送时限,1s
    setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&opt,sizeof(int));    
                                       //设置接收时限,1s
pid=fork();
    if(pid==-1){
        perror("fork");
        exit(1);
    }
    else if(pid==0){
    //发消息给服务端
    if((sendbytes=send(sockfd,"hello world\n",MAXDATASIZE,MSG_DONTWAIT))==-1){
                    //MSG_DONTWAIT设置发送方式是非阻塞的,如此可不用设置讨接字的非阻塞属性
        perror("send");
        exit(1);
    }
   
    }else{
        sleep(3);
        if(recv(sockfd,buf,MAXDATASIZE,MSG_DONTWAIT)==-1){
            perror("recv");
            exit(1);       
        }
        fprintf(stderr,"recv %s from %s \n",buf,inet_ntoa(serv_addr.sin_addr));
    }
有接收有发送

服务端:
if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){        
        perror("recv");
        exit(1);
    }
    printf("receveived: %s\n",buf);   

仅接收,不发送

客户端执行结果:
zlm8715@zlm8715-desktop:~/zlmdata$ ./client  192.168.199.129
connect 192.168.199.129 is success!
recv: Resource temporarily unavailable
此处接收错误,是因为客户端接收的flags设置为MSG_DONTWAIT,即非阻塞,而且设置了接收、发送时限为1s。
若flags设为0,则客户端会一直阻塞在recv().
相关阅读 更多 +
排行榜 更多 +
鹰眼IV

鹰眼IV

飞行射击 下载
火柴人史诗射手

火柴人史诗射手

飞行射击 下载
10发子弹安卓版

10发子弹安卓版

飞行射击 下载