LinuxSir.cn,穿越时空的Linuxsir!

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

socket编程 : recvfrom的问题

[复制链接]
发表于 2005-6-27 15:30:35 | 显示全部楼层 |阅读模式
ssize_t  recvfrom(int s, void *buf, size_t len, int flags, struct sock-addr *from, socklen_t *fromlen);

最后一个参数为socklen_t*类型,我看不少书上都用int*代替,可以编译通过,可是却给warning. 有什么更好的办法吗?
发表于 2005-6-27 17:23:54 | 显示全部楼层
int*是早期的使用方法,,,你可以使用socklen_t*代替,,两个都可以用,,不过我试过用int*编译不了,,还不知是什么原因,,一般都是可以编译过的...有警告也难免的啦~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-27 17:38:44 | 显示全部楼层
Post by zjyu88
int*是早期的使用方法,,,你可以使用socklen_t*代替,,两个都可以用,,不过我试过用int*编译不了,,还不知是什么原因,,一般都是可以编译过的...有警告也难免的啦~~


socklen_t*我也想用,可惜我不知道是哪个头文件里的。
回复 支持 反对

使用道具 举报

发表于 2005-6-28 09:28:43 | 显示全部楼层
sys/types.h
还是用socklen_t好,在其它amd64上int会出错的。
回复 支持 反对

使用道具 举报

发表于 2005-6-28 16:28:09 | 显示全部楼层
socklen_t保证了在不同体系结构上的可移植性。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-6-28 16:58:55 | 显示全部楼层
改用socklen_t*还是有警告(#inlcude <unistd.h> #inlucde <sys/types.h>):
warning: passing arg 5 of `recvfrom' from incompatible pointer type

源码是这样的:

  1. socklen_t sin_len;
  2. sin_len = sizeof(sin); /*sin is a struct sockaddr_in*/
  3. recvfrom(..., & sin_len);
复制代码


$ gcc --version
gcc (GCC) 3.2.3 20030502 (Asianux 1.0 3.2.3-36)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
Linux Freedom 2.4.26-1smp #1 SMP 一 9月 27 23:57:50 EDT 2004 i686 i686 i386 GNU/Linux


Post by kj501
socklen_t保证了在不同体系结构上的可移植性。

有道理,对于recfrom的第5个参数,不同系统上有所不同,可是POSIX规定的是socklen_t*。

Post by 小锁
sys/types.h
还是用socklen_t好,在其它amd64上int会出错的。

我觉得是在unistd.h里声明的吧:
unistd.h:   typedef __socklen_t socklen_t;
回复 支持 反对

使用道具 举报

发表于 2005-6-28 19:58:04 | 显示全部楼层
socket的man页有一段说明,这个长度就是一个int型, posix凑了个socklen_t出来。

$ man accept
NOTE
     The  third  argument  of  accept was originally declared as an `int *' (and is that under libc4 and libc5 and on many other systems
       like BSD 4.*, SunOS 4, SGI); a POSIX 1003.1g draft standard wanted to change it into a `size_t *', and that is what it is for SunOS
       5.  Later POSIX drafts have `socklen_t *', and so do the Single Unix Specification and glibc2.  Quoting Linus Torvalds:

       "_Any_  sane library _must_ have "socklen_t" be the same size as int.  Anything else breaks any BSD socket layer stuff.  POSIX ini-
       tially _did_ make it a size_t, and I (and hopefully others, but obviously not too many) complained  to  them  very  loudly  indeed.
       Making  it a size_t is completely broken, exactly because size_t very seldom is the same size as "int" on 64-bit architectures, for
       example.  And it _has_ to be the same size as "int" because that's what the BSD socket interface  is.   Anyway,  the  POSIX  people
       eventually  got a clue, and created "socklen_t".  They shouldn't have touched it in the first place, but once they did they felt it
       had to have a named type for some unfathomable reason (probably somebody didn't like losing face  over  having  done  the  original
       stupid thing, so they silently just renamed their blunder)."

$ man connect
NOTE
       The third argument of connect is in reality an int (and this is what BSD 4.* and libc4  and  libc5  have).   Some  POSIX  confusion
       resulted in the present socklen_t, also used by glibc.  See also accept(2).

$ man recvfrom
NOTE
       The prototypes given above follow glibc2.  The Single Unix Specification agrees, except that it has return values of type `ssize_t'
       (while BSD 4.* and libc4 and libc5 all have `int').  The flags argument is `int' in BSD 4.*, but `unsigned int' in libc4 and libc5.
       The  len  argument  is  `int'  in  BSD 4.*, but `size_t' in libc4 and libc5.  The fromlen argument is `int *' in BSD 4.*, libc4 and
       libc5.  The present  `socklen_t *' was invented by POSIX.  See also accept(2).
回复 支持 反对

使用道具 举报

发表于 2005-6-28 21:04:44 | 显示全部楼层
引自unp v1:

ANSI C invented the size_t datatype, which is used, for example, as the argument to malloc (the number of bytes to allocate), and as the third argument to read and write (the number of bytes to read or write). On a 32-bit system, size_t is a 32-bit value, but on a 64-bit system, it must be a 64-bit value, to take advantage of the larger addressing model. This means a 64-bit system will probably contain a typedef of size_t to be an unsigned long. The networking API problem is that some drafts of POSIX.1g specified that function arguments containing the size of a socket address structures have the size_t datatype (e.g., the third argument to bind and connect). Some XTI structures also had members with a datatype of long (e.g., the t_info and t_opthdr structures). If these had been left as is, both would change from 32-bit values to 64-bit values when a Unix system changes from the ILP32 to the LP64 model. In both instances, there is no need for a 64-bit datatype: The length of a socket address structure is a few hundred bytes at most, and the use of long for the XTI structure members was a mistake.
The solution is to use datatypes designed specifically to handle these scenarios. The sockets API uses the socklen_t datatype for lengths of socket address structures, and XTI uses the t_scalar_t and t_uscalar_t datatypes. The reason for not changing these values from 32 bits to 64 bits is to make it easier to provide binary compatibility on the new 64-bit systems for applications compiled under 32-bit systems.
回复 支持 反对

使用道具 举报

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

本版积分规则

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