创建一个socket:
int socket(int domain, int type, int protocol);
domain(常用几个):
PF_UNIX,PF_LOCAL 本地通信
PF_INET IPV4
PF_INET6 IPV6
PF_PACKET 数据链路层直接获取数据包接口
PF_KEY 密钥socket(IPSec)
type:
SOCK_STREAM 面向连接、可靠的、双工通信
SOCK_DGRAM 无连接、不可靠的数据报
SOCK_SEQPACKET 顺序,可靠,双工
SOCK_RAW 原始网络协议(用户可以自定义数据报包头)
SOCK_RDM 可靠数据,但不保证数据报顺序
SOCK_PACKET 据说不要再使用了
protocol即要使用的协议IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP。
socket系统调用过程:socket在gclibc中通过_syscall1()在内核中通过sys_socketcall()-
>sys_socket()创建一个通信socket, sys_socket()主要做了两件事情:创建一个代表通讯端点的
结构体struct socket,将这个结构映射到一个文件描述符上,最后将这个描述符返回,也就是我
们调用socket得到的套接字描述符。
struct socket {
socket_state state;
short type;
unsigned long flags;
const struct proto_ops *ops;
struct fasync_struct *fasync_list;
struct file *file;
struct sock *sk;
wait_queue_head_t wait;
}; //include/linux/net.h
typedef enum {
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;
结构体sock是套接口在网络层的表示,在代码include/net/sock.h定义
struct sock {
……
};
__sk_common是套接口在网络层的最小表示。下面是其定义:
struct sock_common {
unsigned short skc_family; /*地址族*/
volatile unsigned char skc_state; /*连接状态*/
unsigned char skc_reuse; /*SO_REUSEADDR设置*/
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node; /*哈希表相关*/
atomic_t skc_refcnt; /*引用计数*/
};
sk_shutdown是一组标志位,SEND_SHUTDOWN and/or RCV_SHUTDOWN。
sk_userlocks, SO_SNDBUF and SO_RCVBUF。
sk_rcvbuf表示接收缓冲区的字节长度。
sk_rmem_alloc表示接收队列已提交的字节数。
sk_receive_queue表示接收的数据包的队列。
sk_wmem_alloc表示发送队列已提交的字节数。
sk_write_queue表示发送数据包的队列。
sk_sndbuf表示发送缓冲区的字节长度。
sk_flags,SO_LINGER (l_onoff),SO_BROADCAST,SO_KEEPALIVE,SO_OOBINLINE。
sk_prot是指定的域内部的协议处理函数集,它是套接口层跟传输层之间的一个接口,提供诸
如bind, accept, close等操作。
sk_ack_backlog表示当前的侦听队列。
sk_max_ack_backlog表示最大的侦听队列。
sk_type表示套接字的类型,如SOCK_STREAM。
sk_protocol表示在当前域中套接字所属的协议。
几个函数指针均属回调函数,分别在套接口状态变化,有数据到达需要处理,有发送空间可
用,有错误等时候被回调。最后一个函数sk_destruct在套接口释放时被回调。
阅读(3833) | 评论(0) | 转发(0) |