Chinaunix

标题: Socket描述符可以是0吗? [打印本页]

作者: feeling    时间: 2005-01-04 12:57
标题: Socket描述符可以是0吗?
初接触UNIX的人都会在教材中得到这样的信息:文件描述符0、1和2分别代表stdin、stdout和stderr。所以,在自己的程序中往往都会避开这几个“标准”的描述符。对于网络的操作,一般在connect(或accept)后都会判断Socket描述符是否大于0来决定网络连接是否建立。

问题偏偏就出在这里。

一个SocketServer程序,accept客户端连接成功后创建一新的线程,将accept的返回值当作该线程的参数。在该线程中和客户端交互,执行所需的操作。

在客户端执行连接操作后,发现连接频频被Server断开,百思不解其意。

经过调试,方才发现在accept执行成功后返回值竟然会是0。

奇怪之余,却又无可奈何,修改Server端程序后问题解决。



操作系统:SunOS 5.8 编译器: SUNWorkspace Pro4.0 CC
作者: albcamus    时间: 2005-01-04 13:07
标题: Socket描述符可以是0吗?
>;>;经过调试,方才发现在accept执行成功后返回值竟然会是0。

真的假的啊?不敢相信的说
作者: _z_    时间: 2005-01-04 13:12
标题: Socket描述符可以是0吗?
你的0,1,2是不是没打开啊?
作者: 思一克    时间: 2005-01-04 13:13
标题: Socket描述符可以是0吗?
accept可以返回0,大于等于0代表成功了
作者: feeling    时间: 2005-01-04 13:29
标题: Socket描述符可以是0吗?
原帖由 "albcamus" 发表:
>;>;经过调试,方才发现在accept执行成功后返回值竟然会是0。

真的假的啊?不敢相信的说

呵,当然是真的了。
作者: yuxh    时间: 2005-01-04 13:38
标题: Socket描述符可以是0吗?
accept之后就得到了0?
一般而言0,1,2被关掉的可能性很小,这里socket应该>;0
是在accept之后打印出来是0还是在线程中打印出来是0?有可能参数传错了呢?
作者: feeling    时间: 2005-01-04 13:58
标题: Socket描述符可以是0吗?
Socket描述符是只有传给线程的:

  1.       int thr_id;
  2.       int *thread_para = new int;
  3.       *thread_para = nsock; // nsock是accept的返回值
  4.       thr_id = pthread_create(&my_thread_id, NULL, start_my_thread, (void*)thread_para);
复制代码

作者: feeling    时间: 2005-01-04 14:00
标题: Socket描述符可以是0吗?
我把accept后的返回值打印出来后,发现的确是可能等于0的。
作者: feeling    时间: 2005-01-04 14:01
标题: Socket描述符可以是0吗?
开始,我也不相信会有这样的事情发生 :-p
现在我开始怀疑connect后的socket描述符是不是也有可能是0呢? ^_^
作者: 思一克    时间: 2005-01-04 14:02
标题: Socket描述符可以是0吗?
这本来就不是什么“事情”吗。
man accept看,ret = -1 失败,》= 0 成功。

具体说,你程序中做了(也可能是隐含的)close(0), accept返回0不就是很好的么。
作者: superdoctor    时间: 2005-01-04 14:11
标题: Socket描述符可以是0吗?
man accpet


  1. RETURN VALUE
  2.        The call returns -1 on error.  If it succeeds, it returns  a  non-nega-
  3.        tive integer that is a descriptor for the accepted socket.
复制代码


没有关掉STDIN返回0的可能性不存在啊
作者: feeling    时间: 2005-01-04 14:12
标题: Socket描述符可以是0吗?
是啊,accept成功后的返回值的确是非负整数。
只是,我被一些教条式的言论蒙蔽了眼睛 ^_^
谁让UNIX下一切都是文件呢?
之前,我一直坚持认为0、1、2都是和“标准”对应的,我们自己弄出来的描述符都是>;=3的 ^_^
作者: yuxh    时间: 2005-01-04 14:15
标题: Socket描述符可以是0吗?
查一下
1、对0socket进行读写操作是否正常?如果正常,就是思一克说的情况
2、thread_para是什么时候delete的?可以试试改成
thr_id = pthread_create(&my_thread_id, NULL, start_my_thread, (void*)nsock);

start_my_thread(void *arg)
{
nsock = (int)arg;
...
}
作者: 思一克    时间: 2005-01-04 14:17
标题: Socket描述符可以是0吗?
标准的fd自己也可以close
作者: Moonwellatg4    时间: 2005-01-04 14:24
标题: Socket描述符可以是0吗?
Windows里面描述的SOCKET的取值
0~SOCKET_ERROR
作者: feeling    时间: 2005-01-04 14:28
标题: Socket描述符可以是0吗?
原帖由 "superdoctor" 发表:

没有关掉STDIN返回0的可能性不存在啊

事实上对于STDIN没有做什么处理,程序只是fork了一下而已:

  1. switch (fork())
  2.           {
  3.             case -1:
  4.         fprintf(stderr,"bad fork - %s\n",strerror(errno));
  5.         _exit(1);
  6.        
  7.             case 0:
  8.         if (setsid() == -1)
  9.         {
  10.           fprintf(stderr,"bad setsid - %s\n",strerror(errno));
  11.           _exit(1);
  12.         }

  13.         break;
  14.        
  15.             default:
  16.         _exit(0);
  17.           }
复制代码

作者: albcamus    时间: 2005-01-04 14:30
标题: Socket描述符可以是0吗?
问题是,楼主有主动或隐含close(0)吗?
作者: superdoctor    时间: 2005-01-04 14:40
标题: Socket描述符可以是0吗?
楼主把accept那段贴出来吧

accept返回后是立即打印出返回值的还是在其他地方打印的呢?
作者: feeling    时间: 2005-01-04 14:40
标题: Socket描述符可以是0吗?
[quote]原帖由 "albcamus"]问题是,楼主有主动或隐含close(0)吗?[/quote 发表:

有啊,在线程里面:

  1. if(sockfd >; 0)   // 问题在这里
  2. {
  3.   // ...
  4. }
  5. else
  6. {
  7.   //...
  8.   close(sockfd);
  9.   sockfd = -1;
  10.   return NULL;
  11. }
复制代码

单单判断sockfd大于0令我大伤脑筋,调试了许久才发现问题。
我奇怪的地方是Socket描述符可以等于0
作者: albcamus    时间: 2005-01-04 14:47
标题: Socket描述符可以是0吗?
呵呵,原来这样。
我看了一下/proc/self/fd/目录下的文件描述符,除了0、1、2之外,还有一个255也默认打开了,这个是干什么的呢?
作者: feeling    时间: 2005-01-04 14:54
标题: Socket描述符可以是0吗?
原帖由 "albcamus" 发表:
呵呵,原来这样。
我看了一下/proc/self/fd/目录下的文件描述符,除了0、1、2之外,还有一个255也默认打开了,这个是干什么的呢?

不同的机器不尽相同吧,我这里查看是0、1、2、3
作者: albcamus    时间: 2005-01-04 14:58
标题: Socket描述符可以是0吗?
3这么小,是你自己打开的吧?关键我的是255,肯定不是进程自己打开的呀
作者: feeling    时间: 2005-01-04 16:01
标题: Socket描述符可以是0吗?
[quote]原帖由 "albcamus"]3这么小,是你自己打开的吧?关键我的是255,肯定不是进程自己打开的呀[/quote 发表:

嘿嘿,老兄,小心黑客啊!~~
作者: albcamus    时间: 2005-01-04 16:14
标题: Socket描述符可以是0吗?
不好意思!!我在shell里看的,那个fd/目录下全都是shell进程的,搞混了:P

写了小程序     
  1. 1 #include <stdio.h>;
  2.       2 #include <dirent.h>;
  3.       3
  4.       4
  5.       5 int main()
  6.       6 {
  7.       7         DIR *dir;
  8.       8         struct dirent *ptr;
  9.       9         dir = opendir("/proc/self/fd");
  10.      10         while((ptr = readdir(dir))!=NULL)
  11.      11                 printf("%s\n",ptr->;d_name);
  12.      12
  13.      13         closedir(dir);
  14.      14         return 0;
  15.      15 }
复制代码


输出也是0,1,2,3。3是什么呢?我没有打开它呀。
作者: win_hate    时间: 2005-01-04 16:58
标题: Socket描述符可以是0吗?
原帖由 "albcamus" 发表:

输出也是0,1,2,3。3是什么呢?我没有打开它呀。

dir = opendir("/proc/self/fd";

作者: albcamus    时间: 2005-01-04 17:12
标题: Socket描述符可以是0吗?
明白了,呵呵,谢谢斑竹(原来opendir也占用fd的啊)
作者: feeling    时间: 2005-01-05 14:22
标题: Socket描述符可以是0吗?
不识庐山真面目...
作者: cattiger    时间: 2005-01-05 16:56
标题: Socket描述符可以是0吗?
这个问题可能在solaris下会出现,我也遇到过类似的情况,修改程序,一定要注意非负整数这个关键的词,也是C标准接口定义的,如果各位使用IPC通信的时候得到的资源也可能ID=0;
作者: 冷峻花开    时间: 2013-09-15 22:56
在linux高级编程中有一处注释
“因网络中,将0重定向为该socket文件描述符,因此向0写数据相当于向socket写数据”
write(0,buff,sizeof(buff));

作者: csumck    时间: 2013-09-16 09:21
是可以的,只是平时0,1,2这三个fd被标准输入输出出错占用了,你关掉这三个fd后,这三个fd就可以被系统重新使用了,不只是socket,所有的会生成fd的都可能返回0的。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2