#include <arpa/inet.h> definitions for internet operations
#include <netinet/in.h> Internet address family
#include <sys/socket.h> main sockets header
<sys/socket.h>中定义
struct sockaddr
16个字节, socket函数使用
struct sockaddr_storage
128个字节, 定义长的特定的协议地址结构
struct sockaddr {
sa_family_t sa_family; /* Address family */
char sa_data[14]; /* protocol-specific address */
};
/* Structure large enough to hold any socket address
(with the historical exception of AF_UNIX). 128 bytes reserved. */
#if ULONG_MAX > 0xffffffff
# define __ss_aligntype __uint64_t
#else
# define __ss_aligntype __uint32_t
#endif
#define _SS_SIZE 128
#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
struct sockaddr_storage
{
sa_family_t ss_family; /* Address family */
__ss_aligntype __ss_align; /* Force desired alignment. */
char __ss_padding[_SS_PADSIZE];
};
sa_family_t
取值:
* AF_INET
Internet domain sockets for use with IPv4 addresses.
* AF_INET6
Internet domain sockets for use with IPv6 addresses.
* AF_UNIX
UNIX domain sockets.
* AF_UNSPEC
Unspecified
使用sockaddr 定义地址不方便, 因此有<netinet/in.h>中sockaddr_in
和sockaddr_in6
struct sockaddr_in {
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
sizeof (sa_family_t) -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr; /* IPv4 address */
};
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* Transport layer port # */
uint32_t sin6_flowinfo; /* IPv6 flow information */
struct in6_addr sin6_addr; /* IPv6 address */
uint32_t sin6_scope_id; /* IPv6 scope-id */
};
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
sockaddr_un // AF_UNIX使用
创建sockaddr_in toaddr
struct sockaddr_in toAddr;
memset(&toAddr, 0, sizeof(toAddr));
toAddr.sin_family = AF_INET;
toAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
toAddr.sin_port = htons(4000);
特殊地址:
* INADDR_ANY
- 表示所以网卡
* INADDR_BROADCAST
- 表示广播地址
特殊端口: * 0 - 操作系统选择一个可用的端口
网络传输需要注意字节顺序, int发送与接收需要使用对应函数统一字节顺序
<arpa/inet.h>
uint64_t htonll(uint64_t);
uint32_t htonl(uint32_t);
uint16_t htons(uint16_t);
uint64_t ntohll(uint64_t);
uint32_t ntohl(uint32_t);
uint16_t ntohs(uint16_t);
该头文件还包含其他有用的转换函数:
inet_addr
- 将一个点分十进制的IP转换成一个长整数型数
inet_ntoa
- 将一个十进制网络字节序转换为点分十进制IP格式的字符串
inet_ntop
- 支持IPv4 IPv6, “点分十进制”和“二进制整数”之间转换
inet_pton
- 支持IPv4 IPv6, “点分十进制”和“二进制整数”之间转换
int setsockopt(int socket, int level, int option_name,
const void *option_value, socklen_t option_len);
int getsockopt(int socket, int level, int option_name,
void *restrict option_value, socklen_t *restrict option_len);
socket:指向一个打开的套接字描述符
level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6
option_name
:选项名字
option_value
:指向某个变量的指针,setsockopt从option_value
中取得选项待设置的新值,getsockopt把已获取的选项当前值存放在option_value
中。
option_len
: option_value
长度
设置socket 选项
SO_ACCEPTCONN
Socket is accepting connections.
SO_BROADCAST
Transmission of broadcast messages is supported.
SO_DEBUG
Debugging information is being recorded.
SO_DONTROUTE
Bypass normal routing.
SO_ERROR
Socket error status.
SO_KEEPALIVE
Connections are kept alive with periodic messages.
SO_LINGER
Socket lingers on close.
SO_OOBINLINE
Out-of-band data is transmitted in line.
SO_RCVBUF
Receive buffer size.
SO_RCVLOWAT
Receive ``low water mark''.
SO_RCVTIMEO
Receive timeout.
SO_REUSEADDR
Reuse of local addresses is supported.
SO_SNDBUF
Send buffer size.
SO_SNDLOWAT
Send ``low water mark''.
SO_SNDTIMEO
Send timeout.
SO_TYPE
Socket type.
<sys/socket.h>
int socket(int domain, int type, int protocol);
domain - 同sa_family_t
取值, 设定协议族
type -
SOCK_STREAM
tcpSOCK_DGRAM
udpSOCK_SEQPACKET
protocol - 一般填0, 使用默认协议IPPROTO_IP
Internet protocol.IPPROTO_IPV6
Internet Protocol Version 6IPPROTO_ICMP
Control message protocol.IPPROTO_RAW
Raw IP Packets Protocol.IPPROTO_TCP
Transmission control protocol.IPPROTO_UDP
User datagram protocol.return - 当返回大于0, 就是socket fd; 小于等于0, 为失败
int bind(int socket, const struct sockaddr *address,
socklen_t address_len);
socket - socket fd
address - 地址
address_len
- 地址长度return - 大于等于0成功, 小于0失败
int listen(int socket, int backlog);
socket - socket fd
backlog - 等待最大连接数return - 大于等于0成功, 小于0失败
int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len);
socket - socket fd
address - 地址
address_len
- 地址长度return - 大于等于0成功, 小于0失败
int connect(int socket, const struct sockaddr *address,
socklen_t address_len);
socket - socket fd
address - 地址
address_len
- 地址长度return - 大于等于0成功, 小于0失败
** 读和写 ** 写
ssize_t send(int socket, const void *buffer, size_t length, int flags);
ssize_t sendto(int socket, const void *message, size_t length,
int flags, const struct sockaddr *dest_addr,
socklen_t dest_len);
ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
读
ssize_t recv(int socket, void *buffer, size_t length, int flags);
ssize_t recvfrom(int socket, void *restrict buffer, size_t length,
int flags, struct sockaddr *restrict address,
socklen_t *restrict address_len);
ssize_t recvmsg(int socket, struct msghdr *message, int flags);
send rece : 一般使用有连接的Socket, 不允许检索数据源地址 sendto recvfrom: 一般使用无连接的Socket sendmsg recvmsg: 一般使用无连接的Socket
flag - 一般传0 MSG_CTRUNC Control data truncated. MSG_DONTROUTE Send without using routing tables. MSG_EOR Terminates a record (if supported by the protocol). MSG_OOB Out-of-band data. MSG_NOSIGNAL No SIGPIPE generated when an attempt to send is made on a stream-oriented socket that is no longer connected. MSG_PEEK Leave received data in queue. MSG_TRUNC Normal data truncated. MSG_WAITALL Attempt to fill the read buffer.
** 关闭连接 **
int shutdown(int socket, int how);
tcp 需要先shutdown
how -
SHUT_RD
Disables further receive operations.SHUT_WR
Disables further send operations.SHUT_RDWR
Disables further send and receive operations.<unistd.h> int close(int fildes);
关闭 socket fd