进程间通讯-套接字
2023-12-25 09:50:29
介绍
套接字(Socket)是用于进程间通信(IPC)的一种接口技术,它可以协调不同计算机上的进程间的通信,也就是基于网络的通信。同时,它也可以用于同一台计算机上的进程间通信。
套接字通信的方式有多种。以下是一些关于使用套接字进行进程间通信的基础知识:
-
套接字的类型:
- TCP套接字:传输控制协议(Transmission Control Protocol)提供面向连接、可靠的数据传输服务,确保数据包按照发送顺序到达接收端。
- UDP套接字:用户数据报协议(User Datagram Protocol)提供无连接、不可靠但速度快的数据传输服务,不保证数据包的顺序或是否到达。
-
套接字的域:
- AF_INET:这是最常见的套接字域,用于Internet网络,基于IPv4地址。
- AF_INET6:用于Internet网络,基于IPv6地址。
- AF_UNIX 或 AF_LOCAL:用于同一台机器上的进程间通信,使用文件路径作为地址。
-
套接字的创建:
在服务器端和客户端都需要创建套接字。这通常涉及到调用socket()
系统调用,指定套接字的域、类型和协议。 -
服务器端操作:
- 绑定(bind):服务器端需要将其套接字与一个特定的IP地址和端口号关联起来。
- 监听(listen):服务器端设置其套接字进入监听状态,等待客户端的连接请求。
- 接受连接(accept):当有客户端发起连接请求时,服务器端接受这个连接,生成一个新的套接字用于与该客户端通信。
-
客户端操作:
- 连接(connect):客户端需要指定服务器的IP地址和端口号,然后发起连接请求。
-
数据传输:
- 发送(send/recv):通过调用
send()
和recv()
函数,服务器和客户端可以互相发送和接收数据。 - 关闭连接:当通信完成时,双方可以关闭各自的套接字以结束连接。
- 发送(send/recv):通过调用
-
错误处理:
在整个过程中,需要适当处理可能出现的错误,如连接失败、发送或接收数据时的错误等。
实现举例
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
int main() {
int server_sock, client_sock;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len = sizeof(struct sockaddr_in);
char message[100];
// 创建套接字
if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// 绑定套接字到指定地址
if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("binding failed");
exit(EXIT_FAILURE);
}
// 开始监听连接请求
if (listen(server_sock, 5) == -1) {
perror("listening failed");
exit(EXIT_FAILURE);
}
printf("Server is listening on port %d...\n", PORT);
while (1) {
// 接受客户端连接请求
if ((client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_len)) == -1) {
perror("accept failed");
continue;
}
printf("Accepted connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 接收客户端发送的消息
if (recv(client_sock, message, sizeof(message), 0) <= 0) {
perror("recv failed");
close(client_sock);
continue;
}
printf("Received message: %s\n", message);
// 发送回复消息给客户端
strcpy(message, "Hello from server!");
if (send(client_sock, message, strlen(message), 0) <= 0) {
perror("send failed");
close(client_sock);
continue;
}
printf("Sent reply to client\n");
// 关闭与客户端的连接
close(client_sock);
}
// 关闭服务器套接字
close(server_sock);
return 0;
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_IP "127.0.0.1"
#define PORT 8080
int main() {
int client_sock;
struct sockaddr_in server_addr;
char message[100];
// 创建套接字
if ((client_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址信息
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
perror("invalid address / address not supported");
exit(EXIT_FAILURE);
}
// 连接到服务器
if (connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connection failed");
exit(EXIT_FAILURE);
}
printf("Connected to server at %s:%d\n", SERVER_IP, PORT);
// 发送消息给服务器
strcpy(message, "Hello from client!");
if (send(client_sock, message, strlen(message), 0) <= 0) {
perror("send failed");
exit(EXIT_FAILURE);
}
printf("Sent message to server\n");
// 接收服务器的回复
if (recv(client_sock, message, sizeof(message), 0) <= 0) {
perror("recv failed");
exit(EXIT_FAILURE);
}
printf("Received reply from server: %s\n", message);
// 关闭套接字
close(client_sock);
return 0;
}
示例说明
在这个例子中,服务器在本地主机的8080端口上监听连接请求。客户端连接到服务器,并发送一条消息。服务器接收消息,然后回复一条消息给客户端。最后,客户端接收回复并关闭连接。注意,你需要将SERVER_IP变量设置为你的服务器的实际IP地址(在这个例子中,我们使用的是本地回环地址127.0.0.1)。
总结
套接字通信提供了灵活且强大的机制来进行进程间通信,无论是本地还是网络环境。然而,它也相对复杂,需要处理诸如连接管理、数据流控制、错误处理等问题,所以我们再使用的时候,一定要评估好技术方案,是否有必要通过套接字实现进程通讯。
文章来源:https://blog.csdn.net/scy518/article/details/135190925
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!