前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >网络函数listen源码分析

网络函数listen源码分析

原创
作者头像
theanarkh
修改2019-01-10 10:09:41
7430
修改2019-01-10 10:09:41
举报
文章被收录于专栏:原创分享
代码语言:c
复制
static int sock_listen(int fd, int backlog)
{
	struct socket *sock;

	if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)
		return(-EBADF);
	if (!(sock = sockfd_lookup(fd, NULL))) 
		return(-ENOTSOCK);

	if (sock->state != SS_UNCONNECTED) 
	{
		return(-EINVAL);
	}

	if (sock->ops && sock->ops->listen)
		sock->ops->listen(sock, backlog);
	// 设置socket的监听属性,accept函数时用到
	sock->flags |= SO_ACCEPTCON;
	return(0);
}
```
```c
static int inet_listen(struct socket *sock, int backlog)
{
	struct sock *sk = (struct sock *) sock->data;
	// 如果没有绑定端口则绑定一个,并把sock加到sock_array中
	if(inet_autobind(sk)!=0)
		return -EAGAIN;

	/* We might as well re use these. */ 
	/*
	 * note that the backlog is "unsigned char", so truncate it
	 * somewhere. We might as well truncate it to what everybody
	 * else does..
	 */
	if ((unsigned) backlog > 128)
		backlog = 128;
	// 设置syn+已连接队列的最大长度,在tcp.c中用到
	sk->max_ack_backlog = backlog;
	// 防止多次调用listen
	if (sk->state != TCP_LISTEN)
	{	
		// syn+已连接队列长度
		sk->ack_backlog = 0;
		sk->state = TCP_LISTEN;
	}
	return(0);
}
```
```c
// 绑定一个随机的端口,更新sk的源端口字段,并把sk挂载到端口对应的队列中
static int inet_autobind(struct sock *sk)
{
	// 已经绑定了端口则直接返回,否则获取一个随机的端口
	if (sk->num == 0) 
	{
		sk->num = get_new_socknum(sk->prot, 0);
		if (sk->num == 0) 
			return(-EAGAIN);
		put_sock(sk->num, sk);
		sk->dummy_th.source = ntohs(sk->num);
	}
	return 0;
}
listen函数主要的工作包括,设置socket和sock结构体的标记和状态,设置syn和已连接队列的上限。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档