Linux C socket API 介绍

Socket 基础

Socket概念

Socket英文愿意是“插孔”或“插座”,作为BSD UNIX的进程通信机制后,取后一种意思,通常也被称为套接字。使用TCP/IP协议的应用程序通常采用的应用编程是使用UNIX BSD的套接字Socket,来实现网络进程之间的通信。

Socket用于描述IP地址和端口,是一个通信链的句柄,用来实现不同虚拟机或物理机之间的通信。应用程序通过Socket向网络发出请求或应答请求。网络中两个进程通过一个双向的通信连接实现数据的交换,建立网络通信连接至少需要一对Socket,连接的一端称为一个Socket。

具有唯一标识的网络进程可利用 Socket 进行通信,而 Socket 是在应用层和传输层之间的一个抽象层,Socket把TCP/IP层复杂的操作抽象为简单的接口供应用层调用,以实现进程在网络中的通信。TCP/IP协议存在于操作系统中,网络服务是通过操作系统提供的,因此在操作系统中增加支持TCP/IP的系统调用Socket。

socket 通信流程

在Linux系统中,一切皆文件,Socket也不例外,对socket的操作实际上也是对某种特殊文件的读写操作。只不过操作的文件在服务器和客户端各自拥有一个。
下图是最基本的socket 通信流程,也就是最初的网络I/O模型(阻塞I/0模型),注意这里展示的是TCP通信流程。
Linux C socket API 介绍_第1张图片
服务器端:
1.生成一个监听的socket,绑定IP地址和端口号
2.监听客户端的请求,并接受客户端的连接

客户端:
1.创建通信socket,
2.连接到服务器

客户端与服务器通信:
1.客户端连接成功向服务器发送连接状态信息
2.服务器端Accetp返回连接socket
3.客户端使用socket写入数据
4.服务器使用连接socket来接收数据

Socket API

创建socket

int socket(int domain, int type, int protocol)
  • domain
    协议簇/域,通常为AF_INET(IPv4)、AF_INET6(IPv6)
  • type
    套接字类型,主要是SOCK_STREAM(TCP)、SOCK_DGRAM(UDP),另外包括SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
  • protocol
    顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
  • 返回值
    success 返回大于0 的socketfd值,错误, 返回-1, 使用errno得到错误值。

socket绑定

 int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

将socket和对应的端口和地址进行绑定,一般用于绑定服务器的监听socket,以便能够让客户端连接到服务器对应的ip和端口。

  • sockfd
    使用socket接口创建的socket文件描述符
  • addr
    服务器端的通信地址
    其中参数的结构体如下表示
struct sockaddr{
	sa_family_t sa_family;
	char		sa_data[14];
};
  • addrlen
    参数addr的长度
  • 返回值
    bind函数调用成功返回0,否则返回-1,并设置erro;

listen

int listen(int sockfd, int backlog);

服务器端使用listen接口来监听客户端的连接

  • sockfd
    使用socket接口创建的socket文件描述符
  • backlog
    backlog通常被描述为连接队列的限制,理解这个参数需要和accept接口一起,一般accept会返回一个sockfd,如果服务器一直没有调用accpet接口,每次有客户端的连接,那么连接队列就会增加1,那么当连接的队列数达到backlog的数字,那么服务器就不会在监听其他客户端的连接。
  • 返回值
    bind函数调用成功返回0,否则返回-1,并设置erro;

connect

int connect(int sockfd, const struct sockaddr *addr,  socklen_t addrlen);

该接口用于客户端连接服务器

  • sockfd
    使用socket接口创建的socket文件描述符
  • serv_addr
    该参数是可传入的实际结构体为sockaddr_in和sockadd_in6
    sockaddr_in:该结构体存有将要connect的ipv4的网络地址以及端口和协议族
    sockaddr_in6:该结构体存有将要connect的ipv6的网络地址以及端口和协议族
  • addrlen
    为传入参数sockaddr结构体的大小,该参数实际应该是一个传出参数。
  • 返回值
    0-连接成功,-1连接服务器失败。错误值使用errno记录。

accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 

主要用于服务器端接收客户端的连接,当客户端发起连接请求后,accept会返回当前连接客户端的socket信息。

参数同connect 接口

-返回值
成功,返回一个socketfd,这个socketfd记录了连接客户端的信息,服务器使用这个socket同客户端进行通信。

recv/recvfrom

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

recv和recvfrom主要用于接收对等端发送的信息,接收的信息存储于buf参数中。
recvfrom与recv不同之处的主要是前者多了2个参数,src_addr和addrlen,从参数名字就知道这2个参数主要是用于表示该请求的发送者的地址信息,由于UDP通信一般不需要客户端先连接服务器,因此recvfrom通常用于UDP通信,recv用于TCP通信。

  • sockfd
    对于服务器端,sockfd为accept接口返回的socket(注意这个sockfd不为服务器使用socket接口生成的socket),对于客户端,为socket接口生成的socket信息。
  • buf
    存放要发送数据的缓冲区
  • len
    存放发送数据缓冲区的字节大小
  • flags
    接收数据的参数设置信息,一般设置为0,主要有以下几个值(很少用)
    MSG_DONTWAIT:仅支持非阻塞的socket,如果socket为阻塞的,会报EAGAIN 或者 EWOULDBLOCK错误
    MSG_OOB:发送或者接收带外数据
    MSG_WAITALL:等待请求的所有数据到达后才返回
    MSG_PEEK:窥探请求发送的数据类型,主要用于查看请求的前几个字节,判断是文本协议还是二进制协议,然后再针对不同的协议来做不同的操作。
  • src_addr
    消息发送方的地址信息
  • addrlen
    src_addr地址信息的长度
  • 返回值
    成功,返回接收到的实际字节数,错误,返回-1,错误码可以通过errno获取到

send/sendto

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

send/sendto主要用于发送消息给对等方,send主要用于TCP通信,sendto主要用于UDP通信。

  • sockfd
    参数同recv/recvfrom接口的第一个参数信息
  • buf
    要发送的缓冲区信息
  • len
    要发送的缓冲字节长度
  • flags
    主要设置发送信息的标志,一般设置为0,其他标志主要有

MSG_DONTROUTE:告诉内核,目标主机在本地网络,不用查路由表

MSG_DONTWAIT:将单个I/O操作设置为非阻塞模式

MSG_OOB:指明发送的是带外信息

  • dest_addr
    要发送的目标地址信息
  • addrlen
    发送的目标地址长度

其他接口

  • write()
  • read()
  • close():关闭socket
  • gethostbyname():IPv4专用
  • gethostbyaddr():IPv4专用
  • getsocketopt()获取对应socket的选项值
  • setsocketopt()设置对应socket的选项值

socket api 测试代码

Linux C TCP编程(socket编程)

你可能感兴趣的:(零声-linux课程总结,C/C++编程,linux,c语言,网络,socket,api)