使用talk进行通信
客户端和用户端分别使用对方的主机名和IP进行通信,在终端输入如下内容:
talk username@hostname #talk执行命令
效果如下:
通信界面:
使用c语言创建一个简单通信
创建如下c语言程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <pthread.h>
#include <dirent.h>
#include <pwd.h>
#include <errno.h>
#define BASE_DIR "/tmp/chat_pipes"
#define BUFFER_SIZE 1024
// 全局变量
volatile int running = 1;
char self_pipe[256], target_pipe[256];
// 获取当前终端的pts编号(如从/dev/pts/0中提取0)
int get_current_pts() {
char *tty_path = ttyname(STDIN_FILENO);
if (!tty_path) {
perror("ttyname");
exit(EXIT_FAILURE);
}
return atoi(strrchr(tty_path, '/') + 1);
}
// 构建管道路径
void build_pipe_path(char *path, const char *username, int pts_num) {
snprintf(path, 256, "%s/%s_%d", BASE_DIR, username, pts_num);
}
// 接收消息线程
void* receiver(void *arg) {
int fd;
char buffer[BUFFER_SIZE];
// 确保管道存在
mkfifo(self_pipe, 0666);
while ((fd = open(self_pipe, O_RDONLY)) == -1 && running) {
usleep(100000); // 等待管道创建
}
while (running) {
ssize_t count = read(fd, buffer, BUFFER_SIZE);
if (count > 0) {
printf("\r[%s] %s", target_pipe + strlen(BASE_DIR) + 1, buffer);
fflush(stdout);
} else if (count == 0) { // 写端关闭
close(fd);
while ((fd = open(self_pipe, O_RDONLY)) == -1 && running) {
usleep(100000);
}
}
}
close(fd);
return NULL;
}
// 显示在线用户
void list_online_users() {
DIR *dir = opendir(BASE_DIR);
if (!dir) return;
printf("Online users:\n");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_FIFO) {
printf(" - %s\n", entry->d_name);
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
// 创建基础目录
mkdir(BASE_DIR, 0777);
// 获取当前用户信息
struct passwd *pw = getpwuid(getuid());
int current_pts = get_current_pts();
// 构造当前管道路径
build_pipe_path(self_pipe, pw->pw_name, current_pts);
// 参数检查
if (argc != 3) {
fprintf(stderr, "Usage: %s <target_user> <target_pts>\n", argv[0]);
fprintf(stderr, "Example: %s alice 1\n", argv[0]);
list_online_users();
exit(EXIT_FAILURE);
}
// 构建目标管道路径
build_pipe_path(target_pipe, argv[1], atoi(argv[2]));
// 启动接收线程
pthread_t tid;
pthread_create(&tid, NULL, receiver, NULL);
printf("Chat session: %s@%d -> %s@%s\n",
pw->pw_name, current_pts, argv[1], argv[2]);
printf("Type message (Ctrl+C to exit):\n");
// 主循环发送消息
while (running) {
char buffer[BUFFER_SIZE];
if (fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
int fd = open(target_pipe, O_WRONLY | O_NONBLOCK);
if (fd == -1) {
if (errno == ENXIO) {
fprintf(stderr, "\rError: Target user is offline.\n");
} else {
perror("open target pipe");
}
running = 0;
break;
}
write(fd, buffer, strlen(buffer) + 1);
close(fd);
}
}
// 清理
running = 0;
pthread_join(tid, NULL);
unlink(self_pipe);
return 0;
}
#创建用户1
./chat bob 2
Chat session: alice@1 -> bob@2
Type message (Ctrl+C to exit):
Hello Bob!
#创建用户2
./chat alice 1
Chat session: bob@2 -> alice@1
Type message (Ctrl+C to exit):
Hi Alice!`
#查看用户在线情况
./chat
总结
一分耕耘一分收获