简单总结一下 Linux 下的套接字编程,后面有时间再修改补充。

Socket 的协议族

一篇详细讲socket编程的博客

  • Socket 创建
#include <sys/types.h>
#include <sys/socket.h>

int socket(int family, int type, int protocol);
  • Family 分为

SOCK_STREAM:数据流(TCP)
SOCK_DGRAM:数据包(UDP)
SOCK_SEQPACKET:可靠的数据包连接
SOCK_RAW:原始套接字

  • Type 分为

AF_INET、AF_INET6:网络域
AF_UNIX:本地域
网络域需要经过协议栈,本地域不需要,直接拷贝缓存数据。

  • 对应的数据结构
//ipv4对应的是:
struct sockaddr_in {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
    struct in_addr sin_addr;   /* internet address */
};

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};
//ipv6对应的是:
struct sockaddr_in6 {
    sa_family_t     sin6_family;   /* AF_INET6 */ 
    in_port_t       sin6_port;     /* port number */ 
    uint32_t        sin6_flowinfo; /* IPv6 flow information */
    struct in6_addr sin6_addr;     /* IPv6 address */ 
    uint32_t        sin6_scope_id; /* Scope ID (new in 2.4) */
};

struct in6_addr {
    unsigned char   s6_addr[16];   /* IPv6 address */ 
};
//Unix域对应的是:
#define UNIX_PATH_MAX    108

struct sockaddr_un {
    sa_family_t sun_family;               /* AF_UNIX */ 
    char        sun_path[UNIX_PATH_MAX];  /* pathname */ 
};

阻塞和非阻塞

可以设置套接字的阻塞与非阻塞,这会导致读写操作的行为不同,非阻塞模式下函数会立即返回。

缓冲区

内核维护一个发送缓冲和接受缓冲,可以手动设置缓冲区大小。

一般,发送缓冲区大小 8M, 接受缓冲区大小 16M

内核缓冲区有个最大值和最小值,若设置的大小的二倍小于最大值,那么内核会把缓冲区的大小 设置为用户指定大小的二倍

write、send、sendto、sendmsg

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sock, const void *buf, size_t len, int flags);
ssize_t sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
ssize_t sendmsg(int sock, const struct msghdr *msg, int flags);

write、send 主要用于数据流网络中。

sendto、sendmsg 可以用在数据报的网络中(UDP)也可以用在数据流的网络中(TCP)。

这些函数本质上没有区别,只是不同的封装。Socket 的发送操作 实质上仅仅是把数据放入发送缓冲区而已,具体发送时间是不一定的。

阻塞和非阻塞区别在于是否等待发送缓冲区腾出足够的空间。

read、recv、recvfrom、recvmsg

在非阻塞状况下,都是尽量读取数据,没数据也不等待。

阻塞情况下:

  • read

若接受缓冲区没有数据,则 read 一直等待,若有数据则只读能读出来的。

  • 其他几个

没有数据会阻塞等待,若有数据则尽量等待读取到要求读取的长度。

socketpair

匿名套接字,进程通信的一种手段,父子进程(线程)间通信。

int socketpair(int domain, int type, int protocol, int sv[2]);

标签: none

添加新评论