日期:2014-05-16 浏览次数:20979 次
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