日期:2014-05-16 浏览次数:21124 次
linux的内核版本是2.6.18,x86_64.
man里的解释是:
|
EBADF |
The argument s is an invalid descriptor |
我的模拟测试环境是:
前端loadrunner模拟web点击,通过后端的weblogic压自己的服务的时候发现,有时候recv会收到这个错误,意思就是这个fd已经失效了,但是有点不是很明白,所以查询下内核实现,验证下。
首先recv的实现就是调用的recvfrom:
/*
* Receive a datagram from a socket.
*/
asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags)
{
return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
}
asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
struct sockaddr __user *addr, int __user *addr_len)
{
struct socket *sock;
struct iovec iov;
struct msghdr msg;
char address[MAX_SOCK_ADDR];
int err,err2;
struct file *sock_file;
int fput_needed;
sock_file = fget_light(fd, &fput_needed);
if (!sock_file)
return -EBADF;
sock = sock_from_file(sock_file, &err);
if (!sock)
goto out;
msg.msg_control=NULL;
msg.msg_controllen=0;
msg.msg_iovlen=1;
msg.msg_iov=&iov;
iov.iov_len=size;
iov.iov_base=ubuf;
msg.msg_name=address;
msg.msg_namelen=MAX_SOCK_ADDR;
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err=sock_recvmsg(sock, &msg, size, flags);
if(err >= 0 && addr != NULL)
{
err2=move_addr_to_user(address, msg.msg_namelen, addr, addr_len);
if(err2<0)
err=err2;
}
out:
fput_light(sock_file, fput_needed);
return err;
}
从代码内可以看到是fget_light这个函数如果返回NULL,则对外报EBADF