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)
相关推荐
小信丶33 分钟前
Linux curl 命令介绍以及使用示例
linux·运维·服务器
Jtti34 分钟前
服务器重装系统时数据丢失?有哪些方法可以避免
linux·运维·服务器
哎呦,帅小伙哦34 分钟前
Sylar服务器框架——协程调度器
linux·服务器
执键行天涯37 分钟前
【nginx】一般nginx会和目标服务部署在同一台服务器上?
运维·服务器·nginx
2301_7849126937 分钟前
服务器的分类有哪些
运维·服务器
米安网络Lewis40 分钟前
华为的服务器创新之路
运维·服务器·华为
hbz-3 小时前
【HBZ分享】如何规避TCP的洪水攻击
网络·网络协议·tcp/ip
Comedy_宁3 小时前
TCP/IP协议超时重传,以及应用层超时重传一文详解
网络·网络协议·tcp/ip
码思途远4 小时前
NXP i.MX8系列平台开发讲解 - 3.18 Linux tty子系统介绍(一)
linux·nxp·i.mx8m
aliceDingYM4 小时前
Linux python3.6安装mayavi报错
linux·python·ui