首页 > 其他分享 >socket的常用方法

socket的常用方法

时间:2023-09-23 21:34:40浏览次数:35  
标签:addr 常用 socket AF int struct 方法 define

上一篇文章中简单介绍了socket,文章最后贴了一个小小的demo,从函数调用流程来看,其实就能明白socket使用的一个逻辑。那么这篇文章,就深入研究一下,每一个步骤里的每一个参数都是什么意思?

回顾demo

代码段:socket_demo.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int server_socket()
{
    int server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  // 创建socket,返回值实际上就是一个fd
    
    struct sockaddr_in server_addr;  // 配置服务端IP和端口
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");
    server_addr.sin_port = htons(6666);
    bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));  // 将socket和IP以及端口绑定
    listen(server_socket, 20);  // 开始监听
    struct sockaddr_in client_addr;
    socklen_t client_addr_size = sizeof(client_addr);
    while (1) {
        // accept函数会阻塞等待客户端的连接,并返回客户端的socket
        int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_size);
        char str[] = "Hello Socket!";
        send(client_socket, str, sizeof(str), 0);  // 发送Hello Socket给客户端    
        close(client_socket);
    }
    close(server_socket);
    return 0;
}


int client_socket()
{
    int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");
    server_addr.sin_port = htons(6666);
    connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));

    char buffer[15];
    recv(client_socket, buffer, 15, 0);
    printf("Message form server: %s\n", buffer);

    close(client_socket);
    return 0;
}

代码段:common.h

#ifndef _COMMON_H
#define _COMMON_H

extern int server_socket();
extern int client_socket();

#endif  /* _COMMON_H */

细说demo

我不不妨把server和client中的函数调用,做成一个流程去看:

server:

  1. socket()
  2. bind()
  3. listen()
  4. accept()
  5. send()
  6. close()

client:

  1. socket()
  2. connect()
  3. recv()
  4. close()

然后我门再在函数调用流程上开支散叶,细说每一个函数,socket.h 中有每一个函数的原型以及简单的说明,相关的文件我放在文件的末尾:附录1

socket()函数

socket函数的原型是:int socket(int af, int type, int protocol);

返回值:int类型,实际上,socket返回的是一个文件描述符,可以直接使用read和write函数操作这个文件描述符。它通常是一个比较小的数值。这里多一嘴,如果你从log中发现,某次申请到的文件描述符比较大,大是什么概念?大于100都算大!你就应该查看代码是不是又申请文件描述符未close。

参数:

  • int af

    af是Address Family的缩写,翻译为地址族,也就是IP地址类型。在socket.h头文件中,地址族定义了很多,但是目前我们常使用的依然是IPv4的地址类型,即AF_INET,可能会有情况也会遇到使用IPv6类型的地址,即AF_INET6.但是这种情况,比较少见,所以此处不多做讨论。

  • int type

    type就表示使用的socket类型,在第一篇socket系列文章中就已说明,我们常用的socket类型又流式套接字和数据报式套接字。参数分别为:

    • 流式套接字(SOCK_STREAM)
    • 数据报式套接字 (SOCK_DGRAM)
  • int protocol

    protocol表示协议,常用的协议就是TCP和UDP,参数分别为:

    • TCP: IPPROTO_TCP
    • UDP: IPPROTO_UDP

    所以socket常用的调用语句是:

    int server_socket = socket(AF_INET, SOCK_STREAK, IPPROTO_TCP);
    

bind()函数

bind()函数的原型是:int bind(int sock, struct sockaddr * addr, socklen_t addrlen);

返回值:int 类型,表示错误码,正常绑定返回0,否则返回-1,并设置error变量。常见的错误类型包括:

  • EADDRINUSE:指定的端口已经被其他进程占用。
  • EMSGSIZE:提供给套接字的数据报太大。
  • ENOBUFS:系统缓冲区不足。
  • EPROTONOSUPPORT:不支持指定的协议族。
  • EINVAL:提供的参数无效。

参数:

  • int sock : 也就是上面通过socket函数生成的socket文件描述符
  • struct sockaddr * addr : socket地址
  • socklen_t addrlen : socket地址长度
sockaddr结构

上面的addrlen和sock两个参数都没什么好说的,只有addr,可以看到在上面demo中填充addr结构的方式有些特殊,做法是先生成sockaddr_in结构体变量,然后填充该结构体,最后强转成sockaddr结构体。我们不妨来看看这两个结构体:

sockaddr_in结构体:

struct sockaddr_in{
    sa_family_t     sin_family;   //地址族(Address Family),也就是地址类型
    uint16_t        sin_port;     //16位的端口号
    struct in_addr  sin_addr;     //32位IP地址
    char            sin_zero[8];  //不使用,一般用0填充
};

sockaddr结构体:

struct sockaddr{
    sa_family_t  sin_family;   //地址族(Address Family),也就是地址类型
    char         sa_data[14];  //IP地址和端口号
};

可以对比以上两个结构体,发现地址族这个字节是公共的,大家都有。不同的是IP和端口的表述上,对于sockaddr_in结构体,他是将端口和IP分开,这样在赋值的时候可以分开赋值。但是对于sockaddr结构体,如果要写IP和端口,就得对"192.168.1.10:6666"字符串进行特殊处理。

所以为什么会存在sockaddr这样的结构体,而不是直接使用sockaddr_in来代替它?因为sockaddr实际上是兼容了所有的地址族,而后者是对IPv4的实现。这样子是不是就能理解了。

因此bind()函数和sockaddr结构填充最典型的实现代码如下:

	struct sockaddr_in server_addr;
	memset(server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;  // 这里需要注意和socket函数中使用的地址族统一
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");
    server_addr.sin_port = htons(6666);
    bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

listen()函数

listen()函数的原型:int listen(int sock, int backlog);

返回值: int 类型的错误码,正常执行返回0 ,执行异常返回-1,并设置error变量。

参数:

  • int sock : 服务端的socket文件描述符,进入被动监听状态,当没有客户端连接的时候该socket处于睡眠状态,又客户端连接则唤醒。
  • int backlog : 表示最大缓冲队列,socket服务端同时只处理一个socket客户端的事务,此时其他socket等待连接,listen监听到这些客户端之后会将他们放入缓冲区。此参数就表示可以放入缓冲区的socket队列大小。

提醒:listen()只是让服务端socket开始监听,并不能进行连接,相当于是我的店铺早上开门了,但是暂时还不能开始卖包子,因为包子还没熟!!

所以,listen()函数的常用实现是:

	listen(server_socket, 20);

accept()函数

调用到accept()函数的时候包子就输了,现在可以开始卖了!

accept()函数原型:int accept(int sock, struct sockaddr * addr, socklen_t * addrlen);

返回值: int 类型的socket文件描述符。这里出现了server端的第二个套接字。为什么要生成一个新的套接字来和客户端通信而不是使用服务端的套接字呢?因为socket通信并不是一对一的通信,有可能多个客户端都需要通过想用的ip和端口对服务端进行访问,因此每次访问都使用新的套接字进行通信,避免了数据的污染。

参数:

  • int sock : 服务端的socket,表示是该服务端正在接收连接
  • struct sockaddr * addr : 客户端的sockaddr,表示该客户端的地址信息
  • socklen_t * addrlen : 客户端地址长度

上面的sockaddr需要特别注意是客户端的地址信息,accept需要传入这个参数来报错连接过来的客户端的地址信息,方便接下来的通信。

综上,accept()函数常用实现方式:

    struct sockaddr_in client_addr;
    memset(client_addr, 0, sizeof(client_addr));
    socklen_t client_addr_len;
    while (1) {
        int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_size);
        ...
        close(client_socket);
    }

connect()函数

上面服务端执行完accept()函数之后,程序就进入阻塞状态了,指导客户端调用connect()函数连接服务端。connect()函数的原型:int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);

返回值: 与bind函数类似,返回值表示错误码,成功0,失败-1

参数:

  • int sock : 客户端初始化的时候也会新建一个client_socket文件描述符,在这里,client_socket解决了连接从哪里来的问题,能够告诉服务端是谁要和你进行连接
  • struct sockaddr * server_addr : 服务端的地址信息
  • socklen_t addr_len : 服务端地址信息长度

所以connect()也就是客户端的典型实现如下:

    int client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");
    server_addr.sin_port = htons(6666);
    connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));

到这里,客户端与服务端就已经建立了连接,那么建立连接之后可以做点啥呢?我们指导socket是一个通信工具,最重要的目的就是完成两个设备之间的通信问题。所以接下来来看看socket的通信接口。

socket通信接口

如果看这篇文章的你熟悉linux系统编程,相信你对read()write() 函数就再了解不过了。他们的原型分别是:

  • write:ssize_t write(int fd, const void *buf, size_t nbytes);
  • read:ssize_t read(int fd, void *buf, size_t nbytes);

具体的参数就不赘述了,因为原型里面写的很明显了。他们的返回值都表示长度,写入函数返回写入的长度,读取函数返回读到的长度。他们常常和open()函数、close()函数配合使用。这就涉及到Linux系统编程了,不赘述。

而socket通信接口就是对write和read函数的封装而已。

来看send和recv的原型:

  • send: ssize_t send(int fd, const void * buff, size_t nbytes, int flags);
  • recv: ssize_t recv(int fd, void * buff, size_t nbytes, int flags);

很容易看到相比于read和write,只多出一个flags参数。它是一个标志位,用于指定发送操作的行为。具体来说,这个标志位可以是以下值之一:

  • 0:非阻塞模式,如果发送缓冲区已满,则立即返回EAGAIN或EWOULDBLOCK错误;否则,返回0。
  • 1:同步阻塞模式,如果发送缓冲区已满,则等待直到有空间可用或接收方关闭连接;否则,返回0。
  • 2:异步非阻塞模式,如果发送缓冲区已满,则立即返回EAGAIN或EWOULDBLOCK错误;否则,返回发送的字节数。

实际上我们使用过程中如果没有特殊需求,一般都是用非阻塞模式进行传输。

所以收发常用的实现方式:

	send(client_socket, str, sizeof(str), 0);
	recv(client_socket, buffer, sizeof(buffer), 0);

小结

上面的demo说到这里,实际上就已经结束了。记性好的小伙伴可能会发现close()函数还没说,但是有必要说吗?很有必要!是的,所以我要在小结中说说close()函数。

close()函数很简单,就传入一个文件描述符,把这个文件描述符释放就可以了。就这样!然而再Linux系统编程中,忘记释放文件描述符确实常有的事情,而且引起的后果往往就是程序崩溃。

分享我最近写的两个bug,都是文件描述符忘记释放。

bug 1

Linux系统编程中需要使用串口/dev/ttySx 收发数据,收发我写了一个公共的函数sendMessage()recvMessage ,bug就在于receive函数中忘记写close()函数了。我自测的时候由于是少量单次读取串口,所以并没有发现问题,可是当app的小伙伴把app跑起来之后,1分钟必崩,他就是需要持续读串口,500ms一次。最后从Log中发现,最后一次申请到文件描述符已经三千多了。经过排查发现了这个问题。

bug 2

Linux系统编程,调用read函数,由于没有阻塞机制,所以使用epoll进行阻塞读取,使用epoll需要进行创建,“Linux一切皆文件”,所以调用epoll_create()函数会生成epoll的文件描述符,是的,我又忘记释放了。app运行到十分钟左右又会崩溃。

所以,不释放文件描述符,后果真的是惨重的。

附录

附录1 socket.h

#ifndef _SYS_SOCKET_H_
#define	_SYS_SOCKET_H_

/* get the definitions for struct iovec, size_t, ssize_t, and <sys/cdefs.h> */
#include <sys/uio.h>

#if __BSD_VISIBLE
#include <sys/types.h>			/* for off_t, uid_t, and gid_t */
#endif

#ifndef	_SOCKLEN_T_DEFINED_
#define	_SOCKLEN_T_DEFINED_
typedef	__socklen_t	socklen_t;	/* length type for network syscalls */
#endif

#ifndef	_SA_FAMILY_T_DEFINED_
#define	_SA_FAMILY_T_DEFINED_
typedef	__sa_family_t	sa_family_t;	/* sockaddr address family type */
#endif


/*
 * Definitions related to sockets: types, address families, options.
 */

/*
 * Types
 */
#define	SOCK_STREAM	1		/* stream socket */
#define	SOCK_DGRAM	2		/* datagram socket */
#define	SOCK_RAW	3		/* raw-protocol interface */
#define	SOCK_RDM	4		/* reliably-delivered message */
#define	SOCK_SEQPACKET	5		/* sequenced packet stream */
#ifdef _KERNEL
#define	SOCK_TYPE_MASK	0x000F		/* mask that covers the above */
#endif

/*
 * Socket creation flags
 */
#if __BSD_VISIBLE
#define	SOCK_CLOEXEC		0x8000	/* set FD_CLOEXEC */
#define	SOCK_NONBLOCK		0x4000	/* set O_NONBLOCK */
#ifdef _KERNEL
#define	SOCK_NONBLOCK_INHERIT	0x2000	/* inherit O_NONBLOCK from listener */
#endif
#define	SOCK_DNS		0x1000	/* set SS_DNS */
#endif /* __BSD_VISIBLE */

/*
 * Option flags per-socket.
 */
#define	SO_DEBUG	0x0001		/* turn on debugging info recording */
#define	SO_ACCEPTCONN	0x0002		/* socket has had listen() */
#define	SO_REUSEADDR	0x0004		/* allow local address reuse */
#define	SO_KEEPALIVE	0x0008		/* keep connections alive */
#define	SO_DONTROUTE	0x0010		/* just use interface addresses */
#define	SO_BROADCAST	0x0020		/* permit sending of broadcast msgs */
#define	SO_USELOOPBACK	0x0040		/* bypass hardware when possible */
#define	SO_LINGER	0x0080		/* linger on close if data present */
#define	SO_OOBINLINE	0x0100		/* leave received OOB data in line */
#define	SO_REUSEPORT	0x0200		/* allow local address & port reuse */
#define SO_TIMESTAMP	0x0800		/* timestamp received dgram traffic */
#define SO_BINDANY	0x1000		/* allow bind to any address */
#define SO_ZEROIZE	0x2000		/* zero out all mbufs sent over socket */

/*
 * Additional options, not kept in so_options.
 */
#define	SO_SNDBUF	0x1001		/* send buffer size */
#define	SO_RCVBUF	0x1002		/* receive buffer size */
#define	SO_SNDLOWAT	0x1003		/* send low-water mark */
#define	SO_RCVLOWAT	0x1004		/* receive low-water mark */
#define	SO_SNDTIMEO	0x1005		/* send timeout */
#define	SO_RCVTIMEO	0x1006		/* receive timeout */
#define	SO_ERROR	0x1007		/* get error status and clear */
#define	SO_TYPE		0x1008		/* get socket type */
#define	SO_NETPROC	0x1020		/* multiplex; network processing */
#define	SO_RTABLE	0x1021		/* routing table to be used */
#define	SO_PEERCRED	0x1022		/* get connect-time credentials */
#define	SO_SPLICE	0x1023		/* splice data to other socket */
#define	SO_DOMAIN	0x1024		/* get socket domain */
#define	SO_PROTOCOL	0x1025		/* get socket protocol */

/*
 * Structure used for manipulating linger option.
 */
struct	linger {
	int	l_onoff;		/* option on/off */
	int	l_linger;		/* linger time */
};

#if __BSD_VISIBLE

#ifndef _TIMEVAL_DECLARED
#define _TIMEVAL_DECLARED
struct timeval {
	time_t		tv_sec;		/* seconds */
	suseconds_t	tv_usec;	/* and microseconds */
};
#endif

/*
 * Structure used for manipulating splice option.
 */
struct	splice {
	int	sp_fd;			/* drain socket file descriptor */
	off_t	sp_max;			/* if set, maximum bytes to splice */
	struct	timeval	sp_idle;	/* idle timeout */
};

/*
 * Maximum number of alternate routing tables
 */
#define	RT_TABLEID_MAX		255
#define	RT_TABLEID_BITS		8
#define	RT_TABLEID_MASK		0xff

#endif /* __BSD_VISIBLE */

/*
 * Level number for (get/set)sockopt() to apply to socket itself.
 */
#define	SOL_SOCKET	0xffff		/* options for socket level */

/*
 * Address families.
 */
#define	AF_UNSPEC	0		/* unspecified */
#define	AF_UNIX		1		/* local to host */
#define	AF_LOCAL	AF_UNIX		/* draft POSIX compatibility */
#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3		/* arpanet imp addresses */
#define	AF_PUP		4		/* pup protocols: e.g. BSP */
#define	AF_CHAOS	5		/* mit CHAOS protocols */
#define	AF_NS		6		/* XEROX NS protocols */
#define	AF_ISO		7		/* ISO protocols */
#define	AF_OSI		AF_ISO
#define	AF_ECMA		8		/* european computer manufacturers */
#define	AF_DATAKIT	9		/* datakit protocols */
#define	AF_CCITT	10		/* CCITT protocols, X.25 etc */
#define	AF_SNA		11		/* IBM SNA */
#define AF_DECnet	12		/* DECnet */
#define AF_DLI		13		/* DEC Direct data link interface */
#define AF_LAT		14		/* LAT */
#define	AF_HYLINK	15		/* NSC Hyperchannel */
#define	AF_APPLETALK	16		/* Apple Talk */
#define	AF_ROUTE	17		/* Internal Routing Protocol */
#define	AF_LINK		18		/* Link layer interface */
#define	pseudo_AF_XTP	19		/* eXpress Transfer Protocol (no AF) */
#define	AF_COIP		20		/* connection-oriented IP, aka ST II */
#define	AF_CNT		21		/* Computer Network Technology */
#define pseudo_AF_RTIP	22		/* Help Identify RTIP packets */
#define	AF_IPX		23		/* Novell Internet Protocol */
#define	AF_INET6	24		/* IPv6 */
#define pseudo_AF_PIP	25		/* Help Identify PIP packets */
#define AF_ISDN		26		/* Integrated Services Digital Network*/
#define AF_E164		AF_ISDN		/* CCITT E.164 recommendation */
#define AF_NATM		27		/* native ATM access */
#define	AF_ENCAP	28
#define	AF_SIP		29		/* Simple Internet Protocol */
#define AF_KEY		30
#define pseudo_AF_HDRCMPLT 31		/* Used by BPF to not rewrite headers
					   in interface output routine */
#define	AF_BLUETOOTH	32		/* Bluetooth */
#define AF_MPLS         33              /* MPLS */
#define pseudo_AF_PFLOW 34		/* pflow */
#define pseudo_AF_PIPEX 35		/* PIPEX */
#define AF_MAX          36

/*
 * Structure used by kernel to store most
 * addresses.
 */
struct sockaddr {
	__uint8_t    sa_len;		/* total length */
	sa_family_t sa_family;		/* address family */
	char	    sa_data[14];	/* actually longer; address value */
};

/*
 * Sockaddr type which can hold any sockaddr type available
 * in the system.
 *
 * Note: __ss_{len,family} is defined in RFC2553.  During RFC2553 discussion
 * the field name went back and forth between ss_len and __ss_len,
 * and RFC2553 specifies it to be __ss_len.  openbsd picked ss_len.
 * For maximum portability, userland programmer would need to
 * (1) make the code never touch ss_len portion (cast it into sockaddr and
 * touch sa_len), or (2) add "-Dss_len=__ss_len" into CFLAGS to unify all
 * occurrences (including header file) to __ss_len.
 */
struct sockaddr_storage {
	__uint8_t	ss_len;		/* total length */
	sa_family_t	ss_family;	/* address family */
	unsigned char	__ss_pad1[6];	/* align to quad */
	__uint64_t	__ss_pad2;	/* force alignment for stupid compilers */
	unsigned char	__ss_pad3[240];	/* pad to a total of 256 bytes */
};

#ifdef _KERNEL
/*
 * Structure used by kernel to pass protocol
 * information in raw sockets.
 */
struct sockproto {
	unsigned short	sp_family;	/* address family */
	unsigned short	sp_protocol;	/* protocol */
};
#endif /* _KERNEL */

/*
 * Protocol families, same as address families for now.
 */
#define	PF_UNSPEC	AF_UNSPEC
#define	PF_LOCAL	AF_LOCAL
#define	PF_UNIX		AF_UNIX
#define	PF_INET		AF_INET
#define	PF_IMPLINK	AF_IMPLINK
#define	PF_PUP		AF_PUP
#define	PF_CHAOS	AF_CHAOS
#define	PF_NS		AF_NS
#define	PF_ISO		AF_ISO
#define	PF_OSI		AF_ISO
#define	PF_ECMA		AF_ECMA
#define	PF_DATAKIT	AF_DATAKIT
#define	PF_CCITT	AF_CCITT
#define	PF_SNA		AF_SNA
#define PF_DECnet	AF_DECnet
#define PF_DLI		AF_DLI
#define PF_LAT		AF_LAT
#define	PF_HYLINK	AF_HYLINK
#define	PF_APPLETALK	AF_APPLETALK
#define	PF_ROUTE	AF_ROUTE
#define	PF_LINK		AF_LINK
#define	PF_XTP		pseudo_AF_XTP	/* really just proto family, no AF */
#define	PF_COIP		AF_COIP
#define	PF_CNT		AF_CNT
#define	PF_IPX		AF_IPX		/* same format as AF_NS */
#define PF_INET6	AF_INET6
#define PF_RTIP		pseudo_AF_RTIP	/* same format as AF_INET */
#define PF_PIP		pseudo_AF_PIP
#define PF_ISDN		AF_ISDN
#define PF_NATM		AF_NATM
#define PF_ENCAP	AF_ENCAP
#define	PF_SIP		AF_SIP
#define PF_KEY		AF_KEY
#define PF_BPF		pseudo_AF_HDRCMPLT
#define	PF_BLUETOOTH	AF_BLUETOOTH
#define PF_MPLS		AF_MPLS
#define PF_PFLOW	pseudo_AF_PFLOW
#define PF_PIPEX	pseudo_AF_PIPEX
#define	PF_MAX		AF_MAX

/*
 * These are the valid values for the "how" field used by shutdown(2).
 */
#define	SHUT_RD		0
#define	SHUT_WR		1
#define	SHUT_RDWR	2

#if __BSD_VISIBLE
#define SA_LEN(x) ((x)->sa_len)

/* Read using getsockopt() with SOL_SOCKET, SO_PEERCRED */
struct sockpeercred {
	uid_t		uid;		/* effective user id */
	gid_t		gid;		/* effective group id */
	pid_t		pid;
};

/*
 * Definitions for network related sysctl, CTL_NET.
 *
 * Second level is protocol family.
 * Third level is protocol number.
 *
 * Further levels are defined by the individual families below.
 */
#define NET_MAXID	AF_MAX

#define CTL_NET_NAMES { \
	{ 0, 0 }, \
	{ "unix", CTLTYPE_NODE }, \
	{ "inet", CTLTYPE_NODE }, \
	{ "implink", CTLTYPE_NODE }, \
	{ "pup", CTLTYPE_NODE }, \
	{ "chaos", CTLTYPE_NODE }, \
	{ "xerox_ns", CTLTYPE_NODE }, \
	{ "iso", CTLTYPE_NODE }, \
	{ "ecma", CTLTYPE_NODE }, \
	{ "datakit", CTLTYPE_NODE }, \
	{ "ccitt", CTLTYPE_NODE }, \
	{ "ibm_sna", CTLTYPE_NODE }, \
	{ "decnet", CTLTYPE_NODE }, \
	{ "dec_dli", CTLTYPE_NODE }, \
	{ "lat", CTLTYPE_NODE }, \
	{ "hylink", CTLTYPE_NODE }, \
	{ "appletalk", CTLTYPE_NODE }, \
	{ "route", CTLTYPE_NODE }, \
	{ "link", CTLTYPE_NODE }, \
	{ "xtp", CTLTYPE_NODE }, \
	{ "coip", CTLTYPE_NODE }, \
	{ "cnt", CTLTYPE_NODE }, \
	{ "rtip", CTLTYPE_NODE }, \
	{ "ipx", CTLTYPE_NODE }, \
	{ "inet6", CTLTYPE_NODE }, \
	{ "pip", CTLTYPE_NODE }, \
	{ "isdn", CTLTYPE_NODE }, \
	{ "natm", CTLTYPE_NODE }, \
	{ "encap", CTLTYPE_NODE }, \
	{ "sip", CTLTYPE_NODE }, \
	{ "key", CTLTYPE_NODE }, \
	{ "bpf", CTLTYPE_NODE }, \
	{ "bluetooth", CTLTYPE_NODE }, \
	{ "mpls", CTLTYPE_NODE }, \
	{ "pflow", CTLTYPE_NODE }, \
	{ "pipex", CTLTYPE_NODE }, \
}

/*
 * PF_ROUTE - Routing table
 *
 * Four additional levels are defined:
 *	Fourth: address family, 0 is wildcard
 *	Fifth: type of info, defined below
 *	Sixth: flag(s) to mask with for NET_RT_FLAGS
 *	Seventh: routing table to use (facultative, defaults to 0)
 *		 NET_RT_TABLE has the table id as sixth element.
 */
#define NET_RT_DUMP	1		/* dump; may limit to a.f. */
#define NET_RT_FLAGS	2		/* by flags, e.g. RESOLVING */
#define NET_RT_IFLIST	3		/* survey interface list */
#define	NET_RT_STATS	4		/* routing table statistics */
#define	NET_RT_TABLE	5
#define	NET_RT_IFNAMES	6
#define	NET_RT_SOURCE	7
#define	NET_RT_MAXID	8

#define CTL_NET_RT_NAMES { \
	{ 0, 0 }, \
	{ "dump", CTLTYPE_STRUCT }, \
	{ "flags", CTLTYPE_STRUCT }, \
	{ "iflist", CTLTYPE_STRUCT }, \
	{ "stats", CTLTYPE_STRUCT }, \
	{ "table", CTLTYPE_STRUCT }, \
	{ "ifnames", CTLTYPE_STRUCT }, \
	{ "source", CTLTYPE_STRUCT }, \
}

/*
 * PF_UNIX - unix socket tunables
 */
#define NET_UNIX_INFLIGHT	6
#define NET_UNIX_DEFERRED	7
#define NET_UNIX_MAXID		8

#define CTL_NET_UNIX_NAMES { \
	{ 0, 0 }, \
	{ "stream", CTLTYPE_NODE }, \
	{ "dgram", CTLTYPE_NODE }, \
	{ 0, 0 }, \
	{ 0, 0 }, \
	{ "seqpacket", CTLTYPE_NODE }, \
	{ "inflight", CTLTYPE_INT }, \
	{ "deferred", CTLTYPE_INT }, \
}

#define UNPCTL_RECVSPACE	1
#define UNPCTL_SENDSPACE	2
#define NET_UNIX_PROTO_MAXID	3

#define CTL_NET_UNIX_PROTO_NAMES { \
	{ 0, 0 }, \
	{ "recvspace", CTLTYPE_INT }, \
	{ "sendspace", CTLTYPE_INT }, \
}

/*
 * PF_LINK - link layer or device tunables
 */
#define NET_LINK_IFRXQ		1	/* net.link.ifrxq */
#define NET_LINK_MAXID		2

#define CTL_NET_LINK_NAMES { \
	{ 0, 0 }, \
	{ "ifrxq", CTLTYPE_NODE }, \
}

#define NET_LINK_IFRXQ_PRESSURE_RETURN \
				1	/* net.link.ifrxq.pressure_return */
#define NET_LINK_IFRXQ_PRESSURE_DROP \
				2	/* net.link.ifrxq.pressure_drop */
#define NET_LINK_IFRXQ_MAXID	3

#define CTL_NET_LINK_IFRXQ_NAMES { \
	{ 0, 0 }, \
	{ "pressure_return", CTLTYPE_INT }, \
	{ "pressure_drop", CTLTYPE_INT }, \
}

/*
 * PF_KEY - Key Management
 */
#define NET_KEY_SADB_DUMP	1	/* return SADB */
#define NET_KEY_SPD_DUMP	2	/* return SPD */
#define NET_KEY_MAXID		3

#define CTL_NET_KEY_NAMES { \
	{ 0, 0 }, \
	{ "sadb_dump", CTLTYPE_STRUCT }, \
	{ "spd_dump", CTLTYPE_STRUCT }, \
}

/*
 * PF_BPF  not really a family, but connected under CTL_NET
 */
#define NET_BPF_BUFSIZE		1		/* default buffer size */
#define NET_BPF_MAXBUFSIZE	2		/* maximum buffer size */
#define NET_BPF_MAXID		3

#define CTL_NET_BPF_NAMES { \
	{ 0, 0 }, \
	{ "bufsize", CTLTYPE_INT }, \
	{ "maxbufsize", CTLTYPE_INT }, \
}

/*
 * PF_PFLOW not really a family, but connected under CTL_NET
 */
#define NET_PFLOW_STATS		1		/* statistics */
#define NET_PFLOW_MAXID		2

#define CTL_NET_PFLOW_NAMES { \
	{ 0, 0 }, \
	{ "stats", CTLTYPE_STRUCT }, \
}
#endif /* __BSD_VISIBLE */

/*
 * Maximum queue length specifiable by listen(2).
 */
#define	SOMAXCONN	128

/*
 * Message header for recvmsg and sendmsg calls.
 * Used value-result for recvmsg, value only for sendmsg.
 */
struct msghdr {
	void		*msg_name;	/* optional address */
	socklen_t	msg_namelen;	/* size of address */
	struct		iovec *msg_iov;	/* scatter/gather array */
	unsigned int	msg_iovlen;	/* # elements in msg_iov */
	void		*msg_control;	/* ancillary data, see below */
	socklen_t	msg_controllen;	/* ancillary data buffer len */
	int		msg_flags;	/* flags on received message */
};

struct mmsghdr {
	struct msghdr msg_hdr;
	unsigned int msg_len;
};

struct timespec;

#define	MSG_OOB			0x1	/* process out-of-band data */
#define	MSG_PEEK		0x2	/* peek at incoming message */
#define	MSG_DONTROUTE		0x4	/* send without using routing tables */
#define	MSG_EOR			0x8	/* data completes record */
#define	MSG_TRUNC		0x10	/* data discarded before delivery */
#define	MSG_CTRUNC		0x20	/* control data lost before delivery */
#define	MSG_WAITALL		0x40	/* wait for full request or error */
#define	MSG_DONTWAIT		0x80	/* this message should be nonblocking */
#define	MSG_BCAST		0x100	/* this message rec'd as broadcast */
#define	MSG_MCAST		0x200	/* this message rec'd as multicast */
#define	MSG_NOSIGNAL		0x400	/* do not send SIGPIPE */
#define	MSG_CMSG_CLOEXEC	0x800	/* set FD_CLOEXEC on received fds */
#define	MSG_WAITFORONE		0x1000	/* nonblocking but wait for one msg */

/*
 * Header for ancillary data objects in msg_control buffer.
 * Used for additional information with/about a datagram
 * not expressible by flags.  The format is a sequence
 * of message elements headed by cmsghdr structures.
 */
struct cmsghdr {
	socklen_t	cmsg_len;	/* data byte count, including hdr */
	int		cmsg_level;	/* originating protocol */
	int		cmsg_type;	/* protocol-specific type */
/* followed by	u_char  cmsg_data[]; */
};

/* given pointer to struct cmsghdr, return pointer to data */
#define	CMSG_DATA(cmsg) \
	((unsigned char *)(cmsg) + _ALIGN(sizeof(struct cmsghdr)))

/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
#define	CMSG_NXTHDR(mhdr, cmsg)	\
	(((char *)(cmsg) + _ALIGN((cmsg)->cmsg_len) + \
			    _ALIGN(sizeof(struct cmsghdr)) > \
	    ((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen) ? \
	    (struct cmsghdr *)NULL : \
	    (struct cmsghdr *)((char *)(cmsg) + _ALIGN((cmsg)->cmsg_len)))

/*
 * RFC 2292 requires to check msg_controllen, in case that the kernel returns
 * an empty list for some reasons.
 */
#define	CMSG_FIRSTHDR(mhdr) \
	((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
	 (struct cmsghdr *)(mhdr)->msg_control : \
	 (struct cmsghdr *)NULL)

/* Round len up to next alignment boundary */
#ifdef _KERNEL
#define CMSG_ALIGN(n)		_ALIGN(n)
#endif

/* Length of the contents of a control message of length len */
#define	CMSG_LEN(len)	(_ALIGN(sizeof(struct cmsghdr)) + (len))

/* Length of the space taken up by a padded control message of length len */
#define	CMSG_SPACE(len)	(_ALIGN(sizeof(struct cmsghdr)) + _ALIGN(len))

/* "Socket"-level control message types: */
#define	SCM_RIGHTS	0x01		/* access rights (array of int) */
#define	SCM_TIMESTAMP	0x04		/* timestamp (struct timeval) */

#ifndef _KERNEL

__BEGIN_DECLS
int	accept(int, struct sockaddr *, socklen_t *);
int	bind(int, const struct sockaddr *, socklen_t);
int	connect(int, const struct sockaddr *, socklen_t);
int	getpeername(int, struct sockaddr *, socklen_t *);
int	getsockname(int, struct sockaddr *, socklen_t *);
int	getsockopt(int, int, int, void *, socklen_t *);
int	listen(int, int);
ssize_t	recv(int, void *, size_t, int);
ssize_t	recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
ssize_t	recvmsg(int, struct msghdr *, int);
int	recvmmsg(int, struct mmsghdr *, unsigned int, int, struct timespec *);
ssize_t	send(int, const void *, size_t, int);
ssize_t	sendto(int, const void *,
	    size_t, int, const struct sockaddr *, socklen_t);
ssize_t	sendmsg(int, const struct msghdr *, int);
int	sendmmsg(int, struct mmsghdr *, unsigned int, int);
int	setsockopt(int, int, int, const void *, socklen_t);
int	shutdown(int, int);
int	sockatmark(int);
int	socket(int, int, int);
int	socketpair(int, int, int, int *);

#if __BSD_VISIBLE
int	accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);
#endif

#if __BSD_VISIBLE
int	getpeereid(int, uid_t *, gid_t *);
int	getrtable(void);
int	setrtable(int);
#endif /* __BSD_VISIBLE */

__END_DECLS

#else

static inline struct sockaddr *
sstosa(struct sockaddr_storage *ss)
{
	return ((struct sockaddr *)(ss));
}

#endif /* !_KERNEL */

#endif /* !_SYS_SOCKET_H_ */

标签:addr,常用,socket,AF,int,struct,方法,define
From: https://blog.51cto.com/klelee/7580749

相关文章

  • 龙哥量化:通达信的macd改进优化方法及选股公式源码
    有很多同学是看macd的数值,遇到股价比较低的,macd数值变成0.00,就看不明白了,优化:第一步,给股价乘100,所有的哦源码:DIF:EMA(CLOSE*100,12)-EMA(CLOSE*100,26);DEA:EMA(DIF,9);MACD:(DIF-DEA)*2,COLORSTICK; 第二步,给macd画参考线,看macd波动幅度N1:=480;DIF:EMA(CLOSE*100,12)-......
  • KGC常用评价指标
    KGC评价指标1.MRMR的全称是MeanRanking,具体的计算方法如下:其中,S是三元组集合,|S|是三元组个数,rank_i是指第i个三元组的链接预测排名。该指标越小越好。2.MRRMRR的全称是MeanReciprocalRanking,其中Reciprocal是指“倒数的”的意思。具体的计算方法如下:其中,S是三元组集......
  • [一些总结]RCE中一些常见的绕过方法
    相关知识网络上有太多人总结了,但还是想自己动动手写点东西加深加深印象,哈哈。命令执行漏洞前提条件:1.存在可调用执行系统命令的函数。2.该函数参数可控。3.对参数过滤不严格。一些常见可以执行命令的函数:1.eval()//把一串字符串作为PHP代码执行2.system()/passthru()/exec......
  • java---常用类
    12.1时间类型(重点)Date类来自于java.util包中,用于显示当前的系统时间。1.语法:importjava.util.Date;Date对象名=newDate();创建了一个当前系统时间对象,如果要获具体的年,月,日,时,分秒的时候工具提示中划删除线的方法代表是过时的方法,过时的方法不建议使用,非要使用也没问题。@Dep......
  • 印象笔记常用快捷键组合
    []1.Ctrl+Alt+N:切换到印象笔记并跳转至一条新笔记[]2.Win+PrintScreen:开启捕捉屏幕[]3.Esc:取消屏幕捕获[]4.Win+A:剪辑选区[]5.Win+Shift+F:在印象笔记中查找(开始一个新的印象笔记搜索)[]6.Ctrl+Alt+V:将剪贴板内容粘贴到印象笔记作为一条新笔记[]7.F9:开始与印象笔记网页版同步......
  • Java中的思想方法
    Java作为一种流行的编程语言,不仅具有简洁、面向对象的特点,还融合了许多重要的思想方法。这些思想方法在Java中贯穿始终,从基本的语法到复杂的框架都得以体现。下面我们将介绍几个在Java中常用的思想方法,并分析它们在编程实践中的应用。一、面向对象编程(OOP)Java是一种纯粹的面向对......
  • Elasticsearch 常用指令
    Elasticsearch常用指令查询所有节点$curl'http://127.0.0.1:9200/_cat/nodes'192.168.31.127496102.162.112.03dilmrt*node-1查询集群状态$curl-k'http://127.0.0.1:9200/_cluster/health?pretty'{"cluster_name":"docker-clus......
  • SVN服务器安装与常用操作(超详细)
    SVN服务器安装与常用操作(超详细)服务器1、下载SVN服务器,地址:http://subversion.apache.org/packages.html进入网址后,滚动到浏览器最底部看到如下截图:  点击,下载 2、在服务器把下载的VisualSVNserver双击安装,文件名:(VisualSVN-Server-4.3.3-x64.msi) 3、点击Next 选择......
  • 想知道如何去图片水印?这几个方法助力你
    如何去图片水印?有没有铁子跟我一样。每天都会在互联网冲浪吃瓜!时间一长难免会刷到一些符合自己喜好的配图或者喜欢的头像图片,配图会想着保存后和朋友分享,头像会想着自己使用。而大多数情况下保存后的图片会有各种各样的水印,那么应如何去图片水印呢?其实我们可以借助一些去图片水印工......
  • SQL Server 常用的系统存储过程
    系统存储过程            说明sp_databases           列出服务器上的所有数据库。sp_helpdb           报告有关指定数据库或所有数据库的信息sp_renamedb           更改数据库的名称sp_tables           返回当......