Linux环境下如何实际对接UNIX端口?实操方法问询
如何实际对接UNIX端口?
核心思路解析
你希望像操作普通文件一样读写网络/端口流,这在Linux下完全可行——UNIX系统的「一切皆文件」哲学正好支持这种需求,不管是UNIX域套接字、硬件串口还是网络端口,都能通过类似文件的接口操作。
实操方案
1. 操作UNIX域套接字
UNIX域套接字本身就是系统中的文件,读写方式和普通文件高度一致,同时支持双向通信。
Bash 实操
创建并监听套接字:
使用socat工具快速搭建套接字服务:socat UNIX-LISTEN:/tmp/my_socket,fork EXEC:/bin/cat这个命令会创建
/tmp/my_socket套接字文件,任何发送到该套接字的内容都会被cat返回(类似echo服务)。读写套接字:
写入内容:echo "hello socket" > /tmp/my_socket读取内容:
cat /tmp/my_socket
C语言实操
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/un.h> #include <sys/socket.h> #define SOCKET_PATH "/tmp/my_socket" int main() { int sockfd; struct sockaddr_un addr; char buffer[1024]; int bytes_read; // 创建套接字 sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 设置地址结构体 memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); // 连接到套接字 if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) { perror("connect"); exit(EXIT_FAILURE); } // 写入数据 const char *msg = "Hello from C program"; write(sockfd, msg, strlen(msg)); // 读取返回数据 bytes_read = read(sockfd, buffer, sizeof(buffer) - 1); if (bytes_read == -1) { perror("read"); exit(EXIT_FAILURE); } buffer[bytes_read] = '\0'; printf("Received: %s\n", buffer); close(sockfd); return 0; }
2. 操作硬件串口
Linux下串口对应/dev/ttyS*或/dev/ttyUSB*设备文件,直接读写即可,但需要先配置串口参数(波特率、奇偶校验等)。
Bash 实操
配置串口(以
/dev/ttyUSB0为例):stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb这里设置波特率9600,8位数据位,无停止位,无奇偶校验。
读写串口:
写入内容:echo "serial test" > /dev/ttyUSB0读取内容:
cat /dev/ttyUSB0
C语言实操
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> int main() { int fd; struct termios options; char buffer[1024]; int bytes_read; // 打开串口设备 fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 获取当前串口配置 tcgetattr(fd, &options); // 设置波特率 cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); // 设置数据位、停止位、奇偶校验 options.c_cflag &= ~PARENB; // 无奇偶校验 options.c_cflag &= ~CSTOPB; // 1位停止位 options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; // 8位数据位 // 应用配置 tcsetattr(fd, TCSANOW, &options); // 写入数据 const char *msg = "Hello from serial"; write(fd, msg, strlen(msg)); // 读取数据 bytes_read = read(fd, buffer, sizeof(buffer) - 1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("Received: %s\n", buffer); } close(fd); return 0; }
3. 操作网络TCP/UDP端口
网络端口本身不是文件,但可以用工具或代码将其映射为类似文件的接口,或者直接用套接字API操作(和UNIX套接字逻辑类似)。
Bash 实操
用socat将TCP端口映射为文件接口:
# 监听TCP 8080端口,并将数据转发到文件接口 socat TCP-LISTEN:8080,fork UNIX-CONNECT:/tmp/net_socket # 此时可以通过/tmp/net_socket读写8080端口
或者直接用nc工具读写:
# 连接到远程端口并发送数据 echo "hello net" | nc example.com 80 # 监听本地端口并接收数据 nc -l 8080
C语言实操
TCP客户端示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 #define SERVER_IP "127.0.0.1" int main() { int sockfd; struct sockaddr_in server_addr; char buffer[1024]; int bytes_read; // 创建TCP套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket"); exit(EXIT_FAILURE); } // 设置服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr); // 连接服务器 if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("connect"); exit(EXIT_FAILURE); } // 发送数据 const char *msg = "Hello from TCP client"; write(sockfd, msg, strlen(msg)); // 接收响应 bytes_read = read(sockfd, buffer, sizeof(buffer) - 1); if (bytes_read == -1) { perror("read"); exit(EXIT_FAILURE); } buffer[bytes_read] = '\0'; printf("Received: %s\n", buffer); close(sockfd); return 0; }
关键说明
- 所有这些操作都遵循Linux的文件权限规则,比如读写套接字或串口文件需要对应的用户权限(可能需要
sudo或加入dialout组)。 - 对于网络端口,虽然没有直接的文件节点,但通过
socat等工具可以模拟出文件接口,满足你用文件操作方式交互的需求。
内容的提问来源于stack exchange,提问作者BrownianBridge
相关产品推荐
相关产品推荐

