关于accept和getpeername的address_len参数的问题
关于accept和getpeername的address_len参数的问题
关于accept和getpeername的address_len参数的问题
socket编程中,难免会有需要取得对端信息的时候
www.2cto.com
socket本身给我们提供了两个方法,accept()和getpeername()
accept()
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
socket:这里的socket是经过bind绑定地址过的socket,可以理解为服务器端的socket。之前有一个监听(listen)操作,accept算是它的后续操作,它们的操作对象都是同一个socket。
www.2cto.com
restrict address:这里的地址变量,用于保存对端的地址信息。
address_len:参数二restrict address的长度,在写入restrict address信息时,也会将写入信息的长度保存到此变量。注意:manpage里对这个参数有一个说明,在使用前必须要初始化,后面继续说明。
返回值:成功会返回对端的socket fd(非负),失败的话会返回-1.(此时获取errno,errmsg是一个好习惯)
getpeername()
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
socket:这里的socket和accept中对应的socket有所不同,它应该是对端的socket。
restrict address:同上
address_len:同上
这里面关于address_len还涉及到一个问题,我就犯过这个错误:使用前,没有初始化。
仔细看看manpage,关于这个参数的,事实是这样的:
以accept为例,当accept收到了client的连接,会做两件事:
1,以address_len的值来写对端信息到restrict address,比如,address_len为1,那么对端的信息,只写1个字节到restrict address(或者因为信息长度为XX,大于1而根本就不写进去,这个可能性更大,有待考证)
2,实际上收到的对端的信息长度写到address_len
所以当你的address_len这个变量没有初始化的时候,其默认值为1(Fedora-16),无法把信息完整写入restrict address,造成没有获取到对端信息的假象。
评论暂时关闭