首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

c语言 linux终端聊天

C语言在Linux终端实现聊天功能涉及多个基础概念,包括进程间通信(IPC)、套接字编程、多线程处理等。以下是对这些概念的详细解释,以及相关的优势、类型、应用场景和可能遇到的问题及解决方法。

基础概念

  1. 进程间通信(IPC)
    • 概念:IPC是指不同进程之间交换信息和协调操作的方式。
    • 类型:包括管道(pipe)、消息队列(message queue)、共享内存(shared memory)、信号量(semaphore)等。
  • 套接字编程
    • 概念:套接字是一种通信端点,允许不同计算机上的进程通过网络进行通信。
    • 类型:常见的有TCP套接字和UDP套接字。
  • 多线程处理
    • 概念:多线程允许一个程序同时执行多个任务,提高程序的并发性和效率。
    • 优势:能够充分利用多核CPU,提高程序的执行速度。

优势

  • 实时性:聊天应用需要实时响应用户的输入和消息传递。
  • 并发性:能够同时处理多个客户端的连接和消息。
  • 跨平台性:Linux终端下的C语言程序可以在不同的Linux系统上运行。

类型

  • 客户端-服务器模型:一个服务器进程负责接收和分发消息,多个客户端进程发送和接收消息。
  • P2P模型:每个参与者既是客户端也是服务器,可以直接相互通信。

应用场景

  • 即时通讯软件:如聊天室、在线游戏中的聊天功能。
  • 远程协作工具:团队成员之间的实时交流。
  • 命令行工具:用于自动化任务和脚本编写中的交互式通信。

示例代码

以下是一个简单的C语言TCP聊天服务器和客户端的示例代码:

服务器端代码

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define MAX_CLIENTS 10

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    fd_set readfds;

    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, MAX_CLIENTS) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    while (1) {
        FD_ZERO(&readfds);
        FD_SET(server_fd, &readfds);
        int max_sd = server_fd;

        for (int i = 0; i < MAX_CLIENTS; i++) {
            int sd = client_socket[i];
            if (sd > 0)
                FD_SET(sd, &readfds);
            if (sd > max_sd)
                max_sd = sd;
        }

        if (select(max_sd + 1, &readfds, NULL, NULL, NULL) < 0) {
            perror("select error");
            exit(EXIT_FAILURE);
        }

        if (FD_ISSET(server_fd, &readfds)) {
            if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
                perror("accept");
                exit(EXIT_FAILURE);
            }
            printf("New connection, socket fd is %d, ip is: %s, port is: %d\n", new_socket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));
            client_socket[num_clients++] = new_socket;
        }

        for (int i = 0; i < num_clients; i++) {
            int sd = client_socket[i];
            if (FD_ISSET(sd, &readfds)) {
                if (read(sd, buffer, 1024) == 0) {
                    getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
                    printf("Host disconnected, ip %s, port %d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                    close(sd);
                    client_socket[i] = 0;
                } else {
                    buffer[1023] = '\0';
                    printf("From client %d: %s\n", i, buffer);
                    for (int j = 0; j < num_clients; j++) {
                        if (client_socket[j] != 0 && client_socket[j] != sd) {
                            send(client_socket[j], buffer, strlen(buffer), 0);
                        }
                    }
                }
            }
        }
    }

    return 0;
}

客户端代码

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char buffer[1024] = {0};

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Socket creation error \n");
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("\nConnection Failed \n");
        return -1;
    }

    while (1) {
        printf("Enter message: ");
        fgets(buffer, 1024, stdin);
        send(sock, buffer, strlen(buffer), 0);
        memset(buffer, 0, sizeof(buffer));
        read(sock, buffer, 1024);
        printf("Server: %s", buffer);
    }

    return 0;
}

可能遇到的问题及解决方法

  1. 连接断开
    • 问题:客户端或服务器意外断开连接。
    • 解决方法:使用心跳机制定期检查连接状态,及时处理断开的连接。
  • 消息丢失
    • 问题:消息在传输过程中丢失。
    • 解决方法:实现消息确认机制,确保每条消息都被正确接收。
  • 性能瓶颈
    • 问题:在高并发情况下,服务器性能下降。
    • 解决方法:使用多线程或多进程处理客户端请求,优化I/O操作。
  • 安全性问题
    • 问题:数据传输可能被窃听或篡改。
    • 解决方法:使用SSL/TLS加密通信,确保数据的安全性。

通过以上方法和示例代码,可以在Linux终端下实现一个基本的C语言聊天功能。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • linux终端和自己聊聊天

    一眨眼已经从劳动节过到青年节了,假期余额已严重不足,马上就要上班了,休息了这么长时间,不知道还会不会敲命令了 起身,下床,翻开笔记本,启动xshell,连接服务器…… 看着终端,突然不知道该输什么命令...我有个习惯,就是每次通过终端连接服务器,都要先输一个w命令 这个命令有几个很重要的信息 1、我可以确定服务器的启动时间,服务器是否有重启过 2、我可以很直观的看到当前有几个虚拟终端 3、很直观的看到哪些用户通过虚拟终端登录...,登录IP、登录时间、空闲时间 4、很直观的看到服务器负载 5、当前执行的命令 都是很重要的信息 然后呢…… 我做了个很无聊的事情 在linux终端和自己聊天 ?...不仔细看的话,可能看不出来 我其实是在两个终端间切换的 xshell有个快捷键“Alt+[1-9]”切换终端,数字对应终端序号(处处都有学问) 我就这么通过write命令+ ssh登录用户名+ttyname...和自己聊了一会儿 一直觉得放空很奢侈,但偶尔也该停下来等一等灵魂 …… 玩了一会儿,我又加了几个终端 这write起来不方便啊 我用wall给他们群发 ?

    1K10

    Linux原始系统api实现两个终端实时聊天

    今天这篇文章基本上属于之前上学学习 c 语言的回顾了,要实现一个简单的聊天功能,其实还是需要话费一些代价的,这里面还是涉及到比较多的知识的。...比如:套接字相关的使用多线程相关select 模型中心化的聊天架构,以及衍生出的去中心化的架构本文为了简化期间,仅仅实现一个中心化的聊天,因为这个我们比较熟悉,而且在学校里学习 c 语言时,多多少少老师让做实习也是写过的...这就是上述的过程,那,我们如何实现这个程序呢,现来看服务端的代码实现:multi_client_server.c#include #include #include...再者,这个是一个完全在内存中的跑的模型,断电之后,聊天消息,好友关系全部都没有了,而且我们基础版本的聊天室里面,后加入的小伙伴不能接收之前大家都聊了些啥,这多少还差那么点意思,所以,交给你来继续完善,你会有思路吗...而且,作为拔高,不防思考一下,如何基于此,实现一个去中心化的聊天服务呢?提示下,最简单的是,端既可以是一个服务端也可以扮演一个客户端。则样 A 和 B 就无需一个固定的服务端了。

    47320

    C语言实现简易聊天室

    C语言聊天室 基于 tcp 实现群聊功能,本项目设计是在「windows环境下基于套接字(Socket)和多线程编程」进行开发的「简易聊天室」,实现了群聊功能,在VC6.0和VS2019运行测试无误。...-1) return -1; name_msg[str_len] = 0; fputs(name_msg, stdout); } return NULL; } 这样就不会阻塞等待终端输入之后再显示服务端发送过来的消息了...「缺陷:非高并发,对资源的利用不高,下周介绍Linux网络编程实现的聊天室,可能有新功能,敬请期待..」...「源代码后台发送关键字windows聊天室获取」 socket网络编程方法可参考上期 C语言实现web服务器 多线程以及线程的同步可通过「阅读全文」在我的个人网站里面查阅。...关键字【聊天室】 -- End --

    3.4K10

    Linux终端的使用

    那就搞个终端设备来操作。因此一台计算机上有很多种不同的终端设备也和正常。也就是说终端就是为主机提供了人机接口,每个人都通过终端使用主机的资源。 终端有字符终端和图形终端两种模式。...在linux的图形环境下,我们可以通过鼠标点击来完成所有的管理任务,这是图形界面终端,另外一种就是文本界面的终端,在这个界面的终端下我们可以使用linux命令来控制系统完成响应的工作,而这个文本终端也是服务器常用的模式...linux命令控制系统的工具,我们点击屏幕左上角的“活动”就可以找到这个它 打开之后我们会看到linux的命令行,在这里面我们可以输入linux命令来进行操作 第二种 打开文本终端,这个需要键盘上的组合键...用户登录 这就是在linux中终端的打开方式,那我们接下来看一下有哪些快捷键 三、常用快捷键 1、图形界面下通过点击屏幕右上角的“活动”按钮打开的终端 [Shift]+[Ctrl]+t 以标签的形式打开一个新的终端...(可用fg恢复) Ctrl+c: 中断终端中正在执行的任务。 Tab键: 命令、文件名等自动补全功能。

    11.8K20

    Linux终端使用总结

    被光标覆盖住)的字符 Ctrl+U —— 删除光标前的所有字符 Ctrl+L —— 清屏 Tab —— 快速补全命令或目录(按一次或当有多个匹配项时两次) Ctrl+Alt+T —— 新建一个终端窗口...) 红色 —— 压缩文件 青色 —— 链接文件(相当于 Windows 快捷方式) 黄色 —— 设备文件 灰色 —— 其他文件 Linux 下的文件类型: 普通文件类型 (-) Linux...块设备(b)和 字符设备(c) 这个种类的文件,是用 mknode 来创建,用 rm 来删除。目前在最新的 Linux 发行版本中,我们一般不用自己来创建设备文件。因为这些文件是和内核相关联的。...引自 Linux 下的 7 种文件类型 - CYYZ 古月 ls -a 显示路径下全部文件(包括隐藏的) ls -l 查看路径下文件的详细信息 tip:在 Linux 下文件夹(目录...、登陆到系统的时间) 关于 tty 设备:(这个没搞太清楚,仅做参考) tty3 - tty6 表示文字界面(文字终端) - Ctrl+Alt+F3~F6 tty2 (?)

    11.3K30

    漫画C语言 做个聊天软件你不懂也得懂

    学完C语言做不出东西?不存在的,咱们做一个最“隐私”的聊天器,就俩人,你和我。咱们聊天的信息你知我知没别人知。...没学过C语言的,觉得难的看这里:https://blog.csdn.net/a757291228/category_11468001.html 我们直接开始写代码,只要你会基础的C语言,不要担心看不懂...,只要你上线了,开电脑打开软件了,连接上我的服务端了,咱们就可以聊天了。...二、开始敲服务端代码 2.1 搞清楚使用 socket 进行通信的步骤 编写C语言Windows下的socket需要经过几个步骤:首先对WSAStartup 进行初始化,初始化对socket 套接字(socket...2.5 有人请求聊天?设置个接待员 接下来就是有人请求给你聊天了,那怎么办呢?一个人忙不过来呢,那就设置个接待员。

    77330

    C语言实现类似QQ聊天界面抖动功能!

    大家好,我们首先来看下下面两张图: 上面两个图片想必大家都见过也用过,那就是QQ的窗口抖动功能,今天给大家带来的就是用C来实现类似QQ窗口抖动的小知识,其实窗口的抖动的原理就是让它在不同的几个位置停顿一小下然后再来回移动...小编给大家推荐一个学习氛围超好的地方,鼠标放到头像上就能看到 原理上面讲了,无非就两点:停顿和移动,那我们来讲一下二者的具体实现,关于停顿我们用到了sleep函数 这里有一点简单提一下,sleep函数在windows和linux...中是不一样的,除了头文件以外,windows中单位为毫秒且S要大写,而linux中为秒,我们这里默认的是windows中,就相当于调用了windows API函数,这就形成了停顿的效果!

    1.8K20

    【Linux笔记】Linux下编译C语言程序

    在上一篇笔记中有分享Linux下的vi/vim编辑器的使用方法(【Linux笔记】Vi/Vim编辑器),现在我们就可以使用vi/vim编辑器编写C代码了。那么写完代码该怎么进行编译呢?...关于在Windows命令行下编译C程序的方法可查看往期笔记:【C语言笔记】windows命令行下编译C程序、【C语言笔记】使用notepad++、MinGW来开发C程序。...首先,使用命令gcc -v查看当前的Linux发行版是否有安装gcc编译器(PS:本文使用的Linux发行版是红帽6): ? 使用vi/vim编辑器写代码并保存为hello.c: ?...在Linux下进行C语言编程的学习可能会增加学习的成本,但是从长远来看仍然是有必要的。...若不想安装Linux系统,也想适应一下Linux环境,则可参考往期笔记:【C语言笔记】Windows下体验Linux环境。

    12.5K10

    linux下的C语言开发

    大家好,又见面了,我是全栈君 在很多人的眼里,C语言和linux常常是分不开的。这其中的原因很多,其中最重要的一部分我认为是linux本身就是C语言的杰出作品。...当然,linux操作系统本身对C语言的支持也是相当到位的。...作为一个真正的程序员来说,如果没有在linux下面用C语言编写过完整的程序,那么只能说他对C语言本身的理解还相关肤浅,对系统本身的认识也不够到位。...如果还没有过Linux编程经验的朋友可以首先在自己的pc上面安装一个虚拟机,然后就可以在shell下面编写自己的C语言代码了。...如果你看到了,那么恭喜你,你已经可以开始linux的c语言编程之旅了。 当然,我们不会满足于这么简单的打印功能。

    5.9K30
    领券