LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3137|回复: 4

如何判断socket断开连接

[复制链接]
发表于 2005-2-25 21:40:21 | 显示全部楼层 |阅读模式
除了看recv返回值还有什么好的方法吗?
以前在windows下方法好多就连select();都能,可是在linux下我试过select就不行.
还有别的方法吗,不知道getsockopt能判断吗,怎么判断。
发表于 2005-2-25 22:07:46 | 显示全部楼层
linux下select当然可以判断连接断开
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-26 22:17:40 | 显示全部楼层
select我怎么没判断出来啊,断开了select还返回1,用select怎么判断啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-27 19:19:46 | 显示全部楼层
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include<unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>

int sock;


int main()
{
        /* init socket */
        struct sockaddr_in addr;
        bzero(&addr,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(7890);
        addr.sin_addr.s_addr=inet_addr("192.168.0.2");
       
        sock=socket(AF_INET,SOCK_STREAM,0);
        if(sock<0)
        {
                perror("cmpp socket error");
                return -1;       
        }
        /* set nonblock */
        int rsflags=fcntl(sock,F_GETFL);
        if(rsflags==-1)
        {
                perror("get rsflags error")        ;
        }
        rsflags|=~O_NONBLOCK;
        fcntl(sock,F_SETFL,rsflags);        //set nonblock
       
        int n=connect(sock,(struct sockaddr *)&addr,sizeof(addr));
       
        while(1)
        {
                        struct timeval tv;
                        fd_set readfds;
                        tv.tv_sec=3;                        //3s timeout
                        tv.tv_usec=0;
                        FD_ZERO(&readfds);
                        FD_SET(sock,&readfds);
                        int ret=select(sock+1,&readfds,NULL,NULL,&tv);
                        printf("\nret=%d",ret);
                        if(ret>0)
                        {
                                char buf[1000];
                                printf("\nhas data");
                                int x=recv(sock,buf,93,0);
                                printf("\nrecv:%d",x);
                        }
                        else if(ret==0)
                        {
                                printf("\ntime out ");
                        }
                        else
                        {
                                //int error=0,errlen=sizeof(int);
                                //getsockopt(sock,SOL_SOCKET,SO_ERROR,&error,&errlen);

                        }
        }
        return 0;       
}

断开连接select 返回1??? 而且我发现执不执行fcntl(sock,F_SETFL,rsflags);都不会阻塞(我发小于94字节的数据),这是怎么回事啊
回复 支持 反对

使用道具 举报

发表于 2005-2-28 16:07:02 | 显示全部楼层
select判断TCP socket 描述符可读的条件是:
1.接收缓冲区的数据大于SO_RCVLOWAT,
2.接收到FIN,也就是对方终止了写.
3.listen套接口接收到请求.
4.套接口有错误处理.

对方断开了有两种情况
1: 调用close, 将套接口标志为关闭,如果套接口的引用计数为0, 则按正常的TCP关闭流程关闭.
2: 调用shutdown关闭写(SHUT_WR),这时直接发送FIN给对方,表示自己不会发送数据了.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表