Linux网络编程——常用套接字函数

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
内容来源
  常用套接字函数整理
  基础套接字函数入门1
  套接字函数及其理解
  socket()函数用法详解:创建套接字
  《Linux网络编程》

1️⃣socket()函数

  函数功能:套接字的初始化:根据用户需求设置套接字的选项。
    在某协议族的某协议中创建一个套接字(socket)【创建socket数据结构分配存储空间】。

项目 说明
函数原型 extern int socket (int __domain, int __type, int __protocol) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.__domain:协议族,设置网络通信的域,如:
AF_INET IPv4协议,AF_INET6 IPv6协议
2.__type:套接字类型,如:
SOCK_STREAM字节流套接字,SOCK_DGRAM数据报套接字,SOCK_RAW原始套接字
3.__protocol:协议编号,指定某协议特定类型(通常取0),如:
IPPROTO_TCPTCP传输协议,IPPROTO_UDPUDP传输协议
返回值 返回新套接字的文件描述符,或-1表示错误,错误可通过errno获得。
注意 ①若__protocol为0,则自动选择1。
②AF(Address Family)与BF(Protocol Family)是相同作用。
③实际前两参数即可创建套接字(推演出协议)除非特殊情况。
#define __CONST_SOCKADDR_ARG	const struct sockaddr *

/* 描述通用套接字地址的结构 */
struct sockaddr
{
     
    __SOCKADDR_COMMON (sa_);	/* 常用数据:地址族和长度 */
    char sa_data[14];	    	/* 14bytes的协议地址数据 */
 };
 
/* 该宏用于声明用于套接字地址的数据类型的初始公共成员,
' struct sockaddr', ' struct sockaddr_in', ' struct sockaddr_un'等 */
#define	__SOCKADDR_COMMON(sa_prefix)  sa_family_t sa_prefix##family

/* POSIX.1g 为' sa_family'成员指定了这个类型名.  */
typedef unsigned short int sa_family_t;

/*
总结:
	sa_family 一般来说,都是 “AFINET”。
	sa_data 包含了一些远程电脑的地址、端口和套接字的数目,它里面的数据是杂溶在一切的。
*/

Linux网络编程——常用套接字函数_第1张图片
Linux网络编程——常用套接字函数_第2张图片
Linux网络编程——常用套接字函数_第3张图片
  调用示例

//创立一个流式套接字
int sock_fd = socket(AF_INET,SOCK_STREAM,0);

2️⃣bind()函数

  函数功能:套接字与端口绑定,即将套接字与地址结构进行绑定,绑定之后,在进行网络程序设计时,套接字所代表IP地址和端口地址及协议类型等参数按绑定值进行操作。
    将套接字描述符(FD)与本机网络地址ADDR(长度为LEN字节)和端口号绑定在一起。
    若使用connect()函数则没有绑定的必要。

项目 说明
函数原型 extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
socket()函数创建的文件描述符。
2.__addr:地址(指向特定协议的地址结构的指针)
包含地址相关信息:名称、端口、IP地址。
(note:需先将地址结构中的数值先设置后才可进行绑定)
3.__len:该地址结构的长度
可设置为 sizeof(struct sockaddr)。
返回值 返回:0表示成功,-1表示错误,错误可通过errno获得。
注意 ①若进行端口监听listen()操作时,等待接收连入请求时,一般都需此步。
②若想要连接服务器connect()操作时,这该步非必须。

Linux网络编程——常用套接字函数_第4张图片

3️⃣connect()函数

  函数功能:连接指定参数的服务器。客户端建立套接字之后,无需进行地址绑定,直接连接服务器。
  在套接字FD上打开一个连接以对等地址ADDR(长度为LEN字节)。对于无连接套接字类型,只需设置发送到的默认地址和接收传输的唯一地址。成功返回0,错误返回-1。

项目 说明
函数原型 extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
socket()函数创建的文件描述符。
2.__addr:地址(指向特定协议的地址结构的指针)
存储远程计算机的IP地址和端口信息的结构。
3.__len:该地址结构的长度
可设置为 sizeof(struct sockaddr)。
返回值 成功返回0,错误返回-1,错误可通过errno获得。
注意 ①这个函数是一个取消点,因此没有__THROW标记。

Linux网络编程——常用套接字函数_第5张图片
  两个服务器函数listen()、accept(),客户端无需这两个函数
  listen()函数是等待别人连接,进行系统侦听请求的函数。当有人连接你的时候,你有两步需要做:通过 listen()函数等待连接请求,然后使用 accept()函数来处理。

4️⃣listen()函数

  函数功能:设置服务器侦听连接,初始化服务器可连接队列,由于服务器需满足多个客户端连接请求,而服务器在某时间仅能处理有限个数的客户端连接请求,故服务器需设置队列长度。
  ①当socket函数创建一个套接字时,默认是主动套接字,listen函数将它变成被动套接字,指示内核应接受指向该套接字的连接请求。调用listen将导致套接字从CLOSED状态转换到LISTEN状态。
  ②第二个参数__n规定了内核应该为相应套接字排队的最大连接个数。内核为任意一个监听套接字维护两个队列,一个叫未完成连接队列,一个叫已完成队列。
    未完成连接队列:每个处于三次握手中的TCP连接,套接字处于SYN_RCVD状态。
    已完成连接队列:每个已完成三次握手的TCP连接,套接字处于ESTABLISHED状态

项目 说明
函数原型 extern int listen (int __fd, int __n) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.int __fd:套接字描述符
2.__n:套接字排队的最大连接个数(建议5~10)
返回值 成功返回0,错误返回-1。错误可通过errno获得。
注意 ①listen()函数调用之前需使用bind()函数指定使用本地哪个端口数值。
②若超过队列长度,客户端会返回一个ECONNREFUSED错误
③仅对SOCK_STREAM或SOCK_SEQPACKET的协议有效

Linux网络编程——常用套接字函数_第6张图片

5️⃣accept()函数

  函数功能:接收客户端连接。当客户端的连接请求到达服务器主机侦听的端口时,此时客户端连接会在队列中等待,直到使用服务器处理接收请求。
    由TCP服务器调用,用于从已完成连接队列的队头返回下一个已完成连接。如果该队列为空,那么进程被投入睡眠。(默认套接字为阻塞方式)

项目 说明
函数原型 extern int accept (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __addr_len);
头文件 sys/types.h、sys/socket.h
参数说明 1.int __fd:套接字描述符
2.__addr:地址(指向特定协议的地址结构的指针)
3.__addr_len:所指内容的长度,如:
可设置为 sizeof(struct sockaddr),此为指针,该函数会将指针传给TCP/IP协议栈。
返回值 成功返回新套接口文件描述符表示客户端连接,客户端连接的信息可通过该描述符获得。
错误返回-1。错误可通过errno获得。
注意 ①如果accept成功,返回值是由内核自动生成的全新描述符,称为已连接套接字。服务端与客户通信,将用这个套接字,服务完成后,这个套接字就被关闭。 而参数__fd称为监听套接字, 一个服务仅仅创建一个监听套接字。
②可得到成功连接客户端IP地址、端口、协议族等信息。当返回时会将客户端信息存入addr中,故这些信息可由addr获得。
③参数__addr和__addr_len返回已连接的对端进程的协议地址,即返回客户端的协议地址。__addr_len是值-结果参数,返回内核存放在协议地址中实际的字节数。如果对客户端的协议地址不感兴趣,可以将指针置为NULL。

Linux网络编程——常用套接字函数_第7张图片

6️⃣send()函数与recv()函数

  函数功能:最基本的通过连接的套接字流进行通讯的函数.
    1️⃣发送N字节的缓存(BUF)到套接字描述符(socket FD)。
    2️⃣从套接字描述符(socket FD)读取N个字节到缓存(BUF)

项目 说明
函数原型 1️⃣extern ssize_t send (int __fd, const void *__buf, size_t __n, int __flags);
2️⃣extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
2.__buf:指向想 发送消息/接收消息 数据的缓冲区地址的指针
3. __n:想要 发送消息/接收消息 缓冲区的最大尺寸
4.__flags:发送/接收标记(一般设置0)
返回值 1️⃣返回真正发送数据的长度,错误返回-1,错误代码存储在全局变量errno中
2️⃣返回真正接收数据的长度,错误返回-1,错误代码存储在全局变量errno中
注意 ①此函数是一个取消点,因此没有标记__THROW。
②send() 所发送的数据可能少于你给它的参数所指定的长度!
③recv()若消息大的缓冲区放不下则会将多余消息砍掉

8️⃣sendto()函数与recvfrom()函数

  函数功能:进行无连接的 UDP 通讯时使用的。使用这两个函数,则数据会在没有建立过任何连接的网络上传输。

项目 说明
函数原型 1️⃣extern ssize_t sendto (int __fd, const void *__buf, size_t __n,int __flags, __CONST_SOCKADDR_ARG __addr,socklen_t __addr_len);
2️⃣extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len);
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
2.__buf:指向想 发送消息/接收消息 数据的缓冲区地址的指针
3. __n:想要 发送消息/接收消息 缓冲区的最大尺寸
4.__flags:发送/接收标记(一般设置0)
5.__addr:指向 struct sockaddr 结构的指针
(包含远程主机的 IP 地址和端口 数据)
6.__addr_len:是指出了 struct sockaddr 在内存中的大小
(一般可设置为sizeof(struct sockaddr))
返回值 1️⃣返回真正发送数据的长度,错误返回-1,错误代码存储在全局变量errno中
2️⃣返回真正接收数据的长度,错误返回-1,错误代码存储在全局变量errno中
注意 ①此函数是一个取消点,因此没有标记__THROW。
②sendto() 所发送的数据可能少于你给它的参数所指定的长度!
③recvfrom()若消息大的缓冲区放不下则会将多余消息砍掉

1️⃣write()函数

  函数功能:服务器端接收一个客户端的连接后,可通过套接字描述符进行数据的写入操作。
     对套接字写入的形式过程与对普通文件操作方式一致。
  示例

int size;
char data[1024];
size = write(s,data,1024);

2️⃣read()函数

  函数功能:与写入数据类似,可通过套接字描述符从中读取数据。
  示例

int size;
char data[1024];
size = read(s,data,1024);

3️⃣close()函数

  函数功能:用于网络传输完毕后,关闭这个套接字描述符所表示的连接。
    执行 close()后,套接字将不会在允许进行读操作和写操作。任何有关对套接字描述符进行读和写的操作都会接收到一个错误。
    在并发服务器中,close函数仅仅将套接字描述符引用计数减1。所以并不能一定在TCP连接上发送FIN报文,如果想在TCP连接上发送FIN报文,可以用shutdown函数

项目 说明
函数原型 extern int close (int __fd);
头文件 unistd.h
参数说明 __fd:套接字描述符
返回值
注意 ①此函数是一个取消点,因此没有标记__THROW。

4️⃣shutdown()函数

  函数功能:可使用更多方式关闭连接。关闭套接字描述符上打开的连接,允许进行单向的关闭操作,部分或全部禁止掉。

项目 说明
函数原型 extern int shutdown (int __fd, int __how) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
2.__how:如何关闭的选项,如:
SHUT_RD= 0 =不再接收,之后不可使用该文件描述符进行读操作;
SHUT_WR= 1 =不再发送,之后不可使用该文件描述符进行写操作;
SHUT_RDWR = 2 =不再接收或发送,之后不可使用该文件描述符进行读与写操作(与close函数相同)。
返回值 成功返回0,错误返回-1。错误可通过errno获得。
注意

Linux网络编程——常用套接字函数_第8张图片

5️⃣setsockopt()函数与 getsockopt() 函数

  函数功能
    1️⃣设置套接字描述符的选项OPTNAME在协议级别level为*OPTVAL(它是OPTLEN字节长)。
    2️⃣ 设置套接字FD的选项OPTNAME在协议级别level为*OPTVAL(它是OPTLEN字节长)。 将套接字FD的选项OPTNAME在协议级别level的当前值放入OPTVAL(它是*OPTLEN字节长),并将*OPTLEN设置为值的

项目 说明
函数原型 extern int setsockopt (int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen) __THROW;
extern int getsockopt (int __fd, int __level, int __optname, void *__restrict __optval, socklen_t *__restrict __optlen) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
2.__level:协议标准
(TCP/IP 协议使用 IPPROTO_TCP, 套接字标准的选项实用 SOL_SOCKET)
3.__optname:
4.__optval:
指向为 getsockopt()函数所获取的值,setsockopt()函数所设置的值的地址。
5.__optlen:
指向一个整数,该整数包含参数以字节计算的长度
返回值 成功返回0,错误返回-1
注意

6️⃣getpeername()函数

  函数功能:将连接socket FD的对端地址输入*ADDR (这是*LEN字节长),它的实际长度为*LEN
以取得一个已经连接上的套接字的远程信息(比如 IP 地址和端口),告诉以取得一个已经连接上的套接字的远程信息(比如 IP 地址和端口),告诉

项目 说明
函数原型 extern int getpeername (int __fd, __SOCKADDR_ARG __addr,socklen_t *__restrict __len) __THROW;
头文件 sys/types.h、sys/socket.h
参数说明 1.__fd:套接字描述符
2.__addr:指向 struct sockaddr (或 struct sockaddr_in)的指针。
3.__len:是一个指向 int 的指针
sizeof(struct sockaddr)的大小。
返回值 错误则返回-1,并将错误代码存储全局变量errno中
注意 当拥有了远程连接用户的 IP 地址,可使用 inet_ntoa() 或 gethostbyaddr()来输 出信息或是做进一步的处理。

8️⃣gethostname()函数

  函数功能:将当前主机的名称以不超过LEN字节的name形式保存。 如果LEN足够大,可以包含全名和结束符,那么结果将以空结束。

项目 说明
函数原型 extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1)) __attr_access ((__write_only__, 1, 2));
头文件 unistd.h
参数说明 1.__name:
指向字符数组的指针,当函数返回的时候,它里面的数据就是本 地的主机的名字
2.__len:
指向的数组的长度
返回值 成功返回0,错误返回-1,全局变量 errno 中存储着错误代码。
注意

()函数

  函数功能

项目 说明
函数原型
头文件 sys/types.h、sys/socket.h
参数说明 1.
2.
3.
返回值
注意

你可能感兴趣的:(书籍学习笔记,嵌入式,linux,网络,运维)