下面是Linux进程间通信——使用流套接字的完整攻略:
1. 简介
在Linux中,进程间通信是一项非常重要的功能。进程间通信(IPC)是指在不同进程之间交换数据或信息的机制。Linux提供了多种IPC方式,包括管道、信号量、共享内存、套接字等。本文将重点讲解Linux中使用流套接字进行进程间通信的方法及注意事项。
2. 流套接字的创建
在Linux中,流套接字的创建可以通过socket
函数来实现。socket
函数的原型如下:
int socket(int domain, int type, int protocol);
其中,domain
参数指明了套接字使用的协议族,一般为AF_UNIX
(Unix域)或AF_INET
(IP域);type
参数指明了套接字的类型,一般为 SOCK_STREAM
(流套接字)或 SOCK_DGRAM
(数据报套接字);protocol
参数表示具体的协议,一般为0,表示使用默认协议。下面是创建流套接字的示例代码:
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#define SOCKET_NAME "/tmp/mysocket"
int main(void)
{
int server_fd;
int client_fd;
struct sockaddr_un server_addr;
struct sockaddr_un client_addr;
socklen_t client_len;
ssize_t recv_len;
char buf[256];
// 创建套接字
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 绑定套接字
memset(&server_addr, 0, sizeof(struct sockaddr_un));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1);
if (bind(server_fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_un)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听客户端连接请求
if (listen(server_fd, 5) == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
// 等待客户端连接
client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_len);
if (client_fd == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
// 读取客户端发送过来的数据
recv_len = recv(client_fd, buf, sizeof(buf), 0);
if (recv_len == -1) {
perror("recv");
exit(EXIT_FAILURE);
}
buf[recv_len] = '\0';
printf("Received message: %s\n", buf);
// 关闭套接字
close(server_fd);
close(client_fd);
// 删除套接字文件
unlink(SOCKET_NAME);
return 0;
}
3. 客户端连接
客户端连接流套接字同样可以使用socket
函数来实现。为了连接到服务器套接字,客户端需要先创建一个客户端套接字并向服务器套接字发出连接请求。下面是客户端连接流套接字的示例代码:
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#define SOCKET_NAME "/tmp/mysocket"
int main(void)
{
int client_fd;
struct sockaddr_un server_addr;
ssize_t send_len;
char buf[256];
// 创建套接字
client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (client_fd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 连接服务器套接字
memset(&server_addr, 0, sizeof(struct sockaddr_un));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1);
if (connect(client_fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_un)) == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
// 向服务器发送数据
strncpy(buf, "Hello, world!", sizeof(buf));
send_len = send(client_fd, buf, strlen(buf), 0);
if (send_len == -1) {
perror("send");
exit(EXIT_FAILURE);
}
printf("Sent message: %s\n", buf);
// 关闭套接字
close(client_fd);
return 0;
}
4. 流套接字的注意事项
在使用流套接字时,需要特别注意以下事项:
-
套接字名必须唯一。Unix域套接字的地址以路径名的形式来表示,因此必须保证路径名在系统中唯一,否则可能会导致套接字创建失败。
-
在使用
recv
函数读取数据时,需要注意其返回值。如果返回0,表示客户端已经关闭连接,此时应该退出程序。如果返回-1,表示读取失败,此时应该检查errno并进行错误处理。 -
在使用
send
函数向服务器发送数据时,需要注意发送的数据长度。如果发送的数据长度超过了套接字缓冲区的大小,可能会导致数据被截断或发送失败。
另外需要注意,Unix域套接字只适用于同一台计算机的进程间通信,如果需要在不同计算机间进行通信,则需要使用IP域套接字。
5. 示例说明
下面是一个使用流套接字进行进程间通信的示例:
# 服务器端(Python)
import socket
def main():
# 创建套接字
server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# 绑定套接字
server_socket.bind('/tmp/mysocket')
# 监听客户端连接请求
server_socket.listen(5)
# 等待客户端连接
client_socket, address = server_socket.accept()
print('Connected by', address)
# 读取客户端发送过来的数据
data = client_socket.recv(1024)
print('Received message:', data.decode())
# 关闭套接字
client_socket.close()
server_socket.close()
if __name__ == '__main__':
main()
# 客户端(Python)
import socket
def main():
# 创建套接字
client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# 连接服务器套接字
client_socket.connect('/tmp/mysocket')
# 向服务器发送数据
message = 'Hello, world!'.encode()
client_socket.send(message)
print('Sent message:', message.decode())
# 关闭套接字
client_socket.close()
if __name__ == '__main__':
main()
以上示例代码中,使用Python语言来创建流套接字,其原理与使用C语言创建流套接字类似,只是语言不同。这两个示例可以作为进一步学习流套接字的参考。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux进程间通信——使用流套接字 - Python技术站