在阿里云服务器使用talk和创建一个简单的c语言程序进行通信

使用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

总结

一分耕耘一分收获

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值