socket编程-----常用socket编程函数

操作系统:Linux

编程语言:C语言

简述:socket编程函数是socket编程中的基础,通过组合使用它们,可以实现各种网络通信功能。
socket编程函数较多,在这里只是列出较为常用的socket函数

socket()函数

socket()函数是网络编程中用于创建新套接字的基本接口。它允许开发者指定套接字的类型、使用的通信协议族以及协议类型,从而创建一个可以用于网络通信的端点。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
int socket(int domain, int type, int protocol);

参数

1、**domain(地址族):**指定协议族,决定了套接字使用的底层协议。常见的协议族包括:

  • AF_INET:IPv4 地址族
  • AF_INET6::IPv6 地址族

2、**type(种类):**指定套接字的类型,决定了通信的方式。常见的套接字类型有:

  • SOCK_STREAM:提供可靠的、面向连接的字节流服务,通常用于 TCP 协议。
  • SOCK_DGRAM:提供无连接的数据报服务,通常用于 UDP 协议。

3、**protocol(协议):**通常设置为 0,表示使用默认的协议。如果为特定的套接字类型指定了非默认的协议,这里可以设置该协议。

  • IPPROTO_TCP:TCP传输协议
  • IPPTOTO_UDP:UDP传输协议

返回值

如果socket()函数成功,它返回一个非负整数,即新创建的套接字的文件描述符。这个文件描述符在后续的网络操作中用于标识和操作该套接字。

如果函数失败,它将返回 -1,并设置全局变量errno以指示错误类型。你可以检查errno的值或使用perror()函数来获取错误信息。

示例

使用IPv4协议、面向连接的数据传输方式、TCP传输协议,来创建套接字

复制代码
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//注意:一般第三个参数protocol直接设置为0即可

bind()函数

bind()函数在网络编程中用于将套接字绑定到特定的地址和端口。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数

  • sockfd:这是一个由socket()函数返回的套接字描述符。
  • addr:这是一个指向sockaddr结构的指针,该结构包含了要绑定的地址和端口信息。对于 IPv4 地址,通常使用sockaddr_in结构体;对于 IPv6 地址,使用sockaddr_in6。
  • addrlen:这是addr参数所指向地址结构的长度,通常使用sizeof(struct sockaddr_in)或sizeof(struct sockaddr_in6)来获取。

返回值

如果bind()函数成功执行,它将返回 0。如果发生错误,它将返回 -1,并设置全局变量errno来指示错误类型。

示例

复制代码
//创建TCP套接字  
int sockfd = socket(AF_INET, SOCK_STREAM, 0);  
if (sockfd == -1) {  
    perror("socket creation failed");  
    exit(EXIT_FAILURE);  
}  

//创建sockaddr_in结构体变量
struct sockaddr_in server_addr;

//设置服务器地址结构  
memset(&server_addr, 0, sizeof(server_addr));  
server_addr.sin_family = AF_INET;//使用IPv4地址
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");监听具体的ip地址  
server_addr.sin_port = htons(12345); // 端口号  

//绑定套接字到地址和端口  
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));

结构体

sockaddr_in结构体
头文件
复制代码
#include <arpa/inet.h>
代码块
复制代码
struct sockaddr_in{ 
    sa_family_t sin_family;    //地址类型 
    uint16_t sin_port;    //16位的端口号 
    struct in_addr sin_addr;    //32位的IP地址 
    char sin_zero[8];    //一般用0填充 
};
in_addr结构体
头文件
复制代码
#include <netinet/in.h>
代码块
复制代码
struct in_addr {  
    in_addr_t s_addr;    //32位的IPv4地址
};
sockaddr结构体
头文件
复制代码
#include <sys/socket.h>
代码块
复制代码
struct sockaddr{ 
    sa_family_t sin_family;    //地址类型 
    char sa_data[14];    //IP地址和端口号 
};

listen()函数

listen()函数用于将套接字设置为监听模式,以便可以接受连接请求。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
int listen(int sockfd, int backlog);

参数

  • sockfd:这是需要被设置为监听模式的套接字描述符,它应该是一个绑定了地址的套接字。
  • backlog:请求队列的最大长度(能存放多少个客户端请求)。实际队列的大小可能比这个值大,也可能小,具体取决于系统实现和可用资源。

返回值

如果函数成功执行,则返回 0。

如果函数执行失败,则返回 -1,并设置全局变量errno以指示错误。

示例

复制代码
//开始监听连接请求  
if (listen(server_fd, 10) == -1) {  
    perror("listen failed");  
    exit(EXIT_FAILURE);  
}  

accept()函数

accept()函数是网络编程中用于接受客户端连接请求的系统调用。当一个客户端尝试连接到服务器时,服务器通过调用accept()函数来接受这个连接,并返回一个新的套接字描述符,用于与客户端进行通信。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数

  • sockfd:这是服务器套接字描述符,即之前通过socket()创建并通过bind()和listen()初始化的套接字。
  • addr:这是一个指向sockaddr 结构体的指针,用于存储客户端的地址信息。如果不需要获取客户端地址,这个参数可以设置为NULL。
  • addrlen:这是一个指向socklen_t类型变量的指针,它用于传入addr结构体的大小,并在调用后返回实际客户端地址的大小。如果addr设置为NULL,则addrlen也应该设置为NULL。

返回值

如果函数成功执行,accept()返回一个新的套接字描述符,这个描述符用于与客户端进行通信。

如果函数执行失败,返回 -1,并设置全局变量errno以指示错误。

示例

复制代码
struct sockaddr_in client_addr; 
sin_size = sizeof(client_addr); 
accept(sockfd, (struct sockaddr *)&client_addr, &sin_size));

connect()函数

connect()函数通常用于在套接字编程中建立客户端与服务器之间的连接。它是 POSIX 套接字 API 的一部分,并且主要用于 TCP 连接。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

参数

sockfd:这是一个套接字描述符,标识了要用于连接的本地端点套接字。它通常是由socket()函数创建的。

serv_addr:这是一个指向sockaddr结构的指针,该结构包含了目标服务器的地址信息。对于 IPv4 地址,通常使用sockaddr_in结构,而对于 IPv6 地址,使用sockaddr_in6结构。

addrlen:这是serv_addr指针指向的sockaddr结构的长度,通常通过sizeof()函数得到。

返回值

如果连接成功,返回 0。

如果连接失败,返回 -1,并设置全局变量errno以指示错误原因。

示例

复制代码
struct sockaddr_in serv_addr;
//连接到服务器  
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {  
    perror("ERROR connecting");  
    exit(1);  
}

send()函数

send()函数用于在套接字编程中发送数据。它是 POSIX 套接字 API 的一部分,可用于 TCP 和 UDP 套接字。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数

sockfd:这是套接字描述符,标识了发送数据的套接字。

buf:这是一个指向要发送数据的缓冲区的指针。

len:这是要发送数据的字节数。

flags:这是控制发送操作的标志位。通常设置为 0,但可以使用特定于协议的标志(如MSG_DONTWATTMSG_OOB等)。一般设置为0。

返回值

如果发送成功,返回实际发送的字节数。

如果发送失败,返回 -1,并设置全局变量errno以指示错误原因。

示例

复制代码
char *message = "Hello, server!";  
int message_len = strlen(message);
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
// 连接到服务器 
connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)
ssize_t sent_bytes = send(sockfd, message, message_len, 0);

recv()函数

recv()函数是一个用于从已连接的套接字接收数据的函数,通常在套接字编程中使用。

头文件

复制代码
#include <sys/socket.h>

函数原型

复制代码
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数

sockfd:接收数据的套接字的文件描述符。

buf:指向缓冲区的指针,该缓冲区用于存储接收到的数据。

len:接收的最大字节数。

flags:这是一组标志,用于修改接收操作的行为。常用的标志包括MSG_WAITALL(等待直到接收到完整的消息)和MSG_DONWAIT(非阻塞接收)。一般设置为0。

返回值

如果成功,recv()函数返回接收到的字节数。

如果套接字已关闭,且没有剩余数据可接收,则返回 0。

如果发生错误,则返回 -1,并设置全局变量errno以指示错误。

示例

复制代码
struct sockaddr_in server_addr;  
char buffer[BUFFER_SIZE];  
ssize_t bytes_received;  
//创建套接字  
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr))
//从服务器接收数据  
bytes_received = recv(sockfd, buffer, BUFFER_SIZE, 0);  

close()或closesocket()函数

close()和closesocket()函数都是用于关闭文件描述符或套接字描述符的。尽管这两个函数在功能上是相似的,但它们通常在不同的编程环境和库中使用。(close()函数在linux系统上使用,closesocket()函数在Windows系统上使用)

头文件

close()函数

复制代码
#include <unistd.h>

closesocket()函数

复制代码
#include <winsock2.h>

函数原型

close()函数

复制代码
int close(int fd);

closesocket()函数

复制代码
int closesocket(SOCKET s);

参数

参数皆为要关闭的套接字

返回值

close()函数

如果成功,返回 0。

如果失败,返回 -1 并设置全局变量errno以指示错误。

closesocket()函数

如果成功,返回 0。

如果失败,返回 SOCKET_ERROR 并设置全局错误码WSAGetLastErrdr()。

示例

close()函数

复制代码
close(sockfd);

closesocket()函数

复制代码
closesocket(sockfd)
相关推荐
你不知道我是谁?17 分钟前
负载均衡--常见负载均衡算法
运维·负载均衡
会又不会42 分钟前
Jenkins-Publish HTML reports插件
运维·jenkins
烟雨书信1 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记1 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花1 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay1 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu1 小时前
redisSearch docker安装
运维·redis·docker·容器
靡樊1 小时前
NAT、代理服务、内网穿透
网络·内网穿透·nat·代理服务·内网打洞
IT成长日记5 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
一只栖枝7 小时前
网络安全 vs 信息安全的本质解析:数据盾牌与网络防线的辩证关系关系
网络·网络安全·信息安全·it·信息安全认证