网络子系统78_inet套接字创建

//	inet协议族控制块
//		1.在inet_init中,由sock_register(&inet_family_ops)注册给系统
// 		2.在sys_socket系统调用中,通过协议族号查找对应的协议控制块,然后由
//		  具体协议控制块的create函数创建套接字
1.1 static const struct net_proto_family inet_family_ops = {
	.family = PF_INET,
	.create = inet_create,
	.owner	= THIS_MODULE,
};

//	为struct socket分配struct inet_sock
//	步骤:
//		0.设置struct socket->state = SS_UNCONNECTED 表示未连接状态
//		1.根据套接字类型,协议号,查找指定协议
//		2.初始化套接字操作集合(socket->ops)
//		3.分配struct sock结构,初始化sock->sk_prot指向inet_protosw->prot
//		4.初始化sock,建立struct sock与struct socket的连接
1.2 static int inet_create(struct net *net, struct socket *sock, int protocol,
		       int kern)
{
	struct sock *sk;
	struct inet_protosw *answer;
	struct inet_sock *inet;
	struct proto *answer_prot;

	int err;

	//未连接状态
	sock->state = SS_UNCONNECTED;

lookup_protocol:
	err = -ESOCKTNOSUPPORT;
	rcu_read_lock();
	//同一协议族下边具有相同套接字类型的多个不同协议
	list_for_each_entry_rcu(answer, &inetsw[sock->type], list) {

		err = 0;

		if (protocol == answer->protocol) {
			if (protocol != IPPROTO_IP)
				break;
		} else {
			//指定IPPROTO_IP表示匹配默认的套接字类型
			if (IPPROTO_IP == protocol) {
				protocol = answer->protocol;
				break;
			}
			//套接字类型的协议号为IPPROTO_IP,表示可以与任何协议匹配
			if (IPPROTO_IP == answer->protocol)
				break;
		}
		err = -EPROTONOSUPPORT;
	}

	//如果模块没有加载,加载协议模块
	...

	//初始化套接字操作,协议类型
	sock->ops = answer->ops; // (struct proto_ops)
	answer_prot = answer->prot; // (struct proto)
	answer_no_check = answer->no_check;
	answer_flags = answer->flags;
	rcu_read_unlock();

	err = -ENOBUFS;
	//分配sock结构
	sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot);
	if (sk == NULL)
		goto out;

	...

	//建立struct sock与struct socket的联系
	sock_init_data(sock, sk);

	...

out:
	return err;
out_rcu_unlock:
	rcu_read_unlock();
	goto out;
}

//	struct sock结构初始化
//		1.分配sock的队列
//		2.初始化sock各字段
//			2.1 sk->sk_state = TCP_CLOSE表示未建立连接
//		3.设置sock->sk_socket字段指向socket
1.3 void sock_init_data(struct socket *sock, struct sock *sk)
{
	//分配sock的队列
	skb_queue_head_init(&sk->sk_receive_queue);
	skb_queue_head_init(&sk->sk_write_queue);
	skb_queue_head_init(&sk->sk_error_queue);
#ifdef CONFIG_NET_DMA
	skb_queue_head_init(&sk->sk_async_wait_queue);
#endif

	sk->sk_send_head	=	NULL;

	init_timer(&sk->sk_timer);

	sk->sk_allocation	=	GFP_KERNEL;
	//接收,发送缓存的大小
	sk->sk_rcvbuf		=	sysctl_rmem_default;
	sk->sk_sndbuf		=	sysctl_wmem_default;
	//未建立连接
	sk->sk_state		=	TCP_CLOSE;
	//sk->sk_socket = socket
	sk_set_socket(sk, sock);

	sock_set_flag(sk, SOCK_ZAPPED);

	if (sock) {
		sk->sk_type	=	sock->type;
		sk->sk_wq	=	sock->wq;
		sock->sk	=	sk;
	} else
		sk->sk_wq	=	NULL;

	sk->sk_state_change	=	sock_def_wakeup;
	sk->sk_data_ready	=	sock_def_readable;
	sk->sk_write_space	=	sock_def_write_space;
	sk->sk_error_report	=	sock_def_error_report;
	sk->sk_destruct		=	sock_def_destruct;

	sk->sk_frag.page	=	NULL;
	sk->sk_frag.offset	=	0;
	sk->sk_peek_off		=	-1;

	sk->sk_peer_pid 	=	NULL;
	sk->sk_peer_cred	=	NULL;
	sk->sk_write_pending	=	0;
	sk->sk_rcvlowat		=	1;
	sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;
	sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;

	sk->sk_stamp = ktime_set(-1L, 0);

	smp_wmb();
	atomic_set(&sk->sk_refcnt, 1);
	atomic_set(&sk->sk_drops, 0);
}
时间: 2024-11-01 00:55:20

网络子系统78_inet套接字创建的相关文章

网络子系统75_套接字创建

// 创建套接字,系统调用sys_socket // 步骤: // 1.分配套接字描述符 // 2.创建套接字对应的文件描述符 // 参数: // 协议族: 对于TCP/IP协议族,该参数为AF_INET // 套接字类型:流套接字类型为SOCK_STREAM, 数据报套接字类型为SOCK_DGRAM // 通信协议: 单个协议系列中的不同传输协议,在internet通信域中,此参数一般取值为0, // 系统根据套接字的类型决定应使用的传输层协议 1.1 SYSCALL_DEFINE3(sock

网络子系统77_套接字接收

// accept系统调用 // 步骤: // 1.由内核公共部分创建一个新套接字描述符,并分配其对应的文件描述符 // 2.新套接字使用accept之上的套接字相同的套接字类型和操作 // 3.交由具体协议完成accept // 4.如果accept调用者要求返回peer地址,通过新套接字获取地址,并复制到用户地址空间 // 5.将新套接字的文件描述安装到调用者的进程控制块,返回新套接字的用户空间文件描述符 1.1 SYSCALL_DEFINE4(accept4, int, fd, struc

网络子系统76_套接字绑定

// 绑定套接字到地址 // 步骤: // 1.根据用户空间的文件描述符查找socket描述符 // 2.复制地址信息到内核空间 // 3.由具体的协议族完成绑定 1.1 SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) { struct socket *sock; struct sockaddr_storage address; int err, fput_needed; //通过用户

[python] 专题七.网络编程之套接字Socket、TCP和UDP通信实例

        很早以前研究过C#和C++的网络通信,参考我的文章:                  C#网络编程之Tcp实现客户端和服务器聊天                 C#网络编程之套接字编程基础知识                 C#网络编程之使用Socket类Send.Receive方法的同步通讯        Python网络编程也类似.同时最近找工作笔试面试考察Socket套接字.TCP\UDP区别比较多,所以这篇文章主要精简了<Python核心编程(第二版)>第16章内

C# 网络编程之套接字编程基础知识

      最近阅读了周存杰编写的<C#网络编程实例教程>并阅读了很多相关方面的资料,同时自己也做了一些套接字编程方面的C#程序,所以根据它的知识总结了最近的套接字编程的一些知识点,方便自己的理解与他人的学习,同时也有一些自己以前学习的计算机网络.操作系统等相关知识. 一.   套接字编程的概念       套接字(Winsock)是一种独立于协议的网络编程接口,在OSI中集中在会话层和传输层.(补充知识)简单回归网络知识,计算机网络中的"五层协议的体系结构"和"

Windows Socket网络编程(二) 套接字编程原理

一.客户机/服务器模式 在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model).该模式的建立基于以下两点:1.非对等作用:2.通信完全是异步的.客户机/服务器模式在操作过程中采取的是主动请示方式: 首先服务器方要先启动,并根据请示提供相应服务:(过程如下) 1.打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求. 2.等待客户请求到达该端口. 3.接收到重复服务请求,处理该请求并发送应答信号. 4.返回第二步,等待另一客户

UNIX网络编程:套接字选项(SOL_SOCKET级别)

#include <sys/socket.h> int setsockopt( int socket, int level, int option_name,const void *option_value, size_t option_len); 第一个参数socket是套接字描述符. 第二个参数level是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为SOL_SOCKET. 第三个参数 option_name指定准备设置的选项,option_name可以有哪些

UNIX网络编程:套接字选项(心跳检测、绑定地址复用)

01./* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. 02. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 03. */ 04.void setKeepAlive( int iSockfd , int iSockAttrOn, socklen_t iIdleTime , socklen_t iInterval , socklen_t iCount ){ 05. setsockopt( iSockfd , SOL_SOCKET , SO_K

网络编程-原始套接字实现SYN扫描,但用wireshark时始终没有发现发出去的包

问题描述 原始套接字实现SYN扫描,但用wireshark时始终没有发现发出去的包 #include #include #include #include #include #include "WS2TCPIP.H" #pragma comment(lib,"Ws2_32.lib") using namespace std; //SOCKADDR_IN target, source; //sockaddr_in target, source; //int sock;