说明: ??本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。 ??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];
};
#define __SOCKADDR_COMMON(sa_prefix) sa_family_t sa_prefix##family
typedef unsigned short int sa_family_t;
??调用示例:
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()操作时,这该步非必须。 |
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标记。 |
??两个服务器函数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的协议有效 |
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。 |
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获得。 | 注意 | | ![在这里插入图片描述](https://img-blog.csdnimg.cn/f80e4608a70a4ccca4b6db58ba8bf12f.png)
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. | 返回值 | | 注意 | |
|