首页 > 其他分享 >使用WebSocket和C语言实现一个简单的计算器

使用WebSocket和C语言实现一个简单的计算器

时间:2024-07-06 11:26:52浏览次数:18  
标签:WebSocket int C语言 result 计算器 go http calc

在现代Web开发中,WebSocket已经成为实时通信的重要工具。本文将介绍如何使用WebSocket与C语言结合,实现一个简单的计算器应用。我们将通过Go语言作为中间层,调用C语言编写的计算函数,并通过WebSocket与前端进行交互。

在使用本文章代码开发过程中遇到问题,可参考博主的另外两篇博客:

解决Go项目开发中遇到的问题(一)-CSDN博客文章浏览阅读647次,点赞23次,收藏10次。Go项目开发中遇到的问题以及对应的解决方案https://blog.csdn.net/qq_45519030/article/details/140202088

解决Go项目开发中遇到的问题(二)-CSDN博客文章浏览阅读660次,点赞17次,收藏20次。Go项目开发中遇到的问题以及对应的解决方案https://blog.csdn.net/qq_45519030/article/details/140203992

项目结构

我们的项目包含以下几个文件:

project/
├── calc.c
├── calc.h
├── client/
│   └── index.html
├── go.mod
├── go.sum
└── main.go

C语言部分

calc.h

#ifndef CALC_H
#define CALC_H
​
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
​
#endif

calc.h 是一个头文件,定义了四个函数原型:addsubtractmultiplydivide。这些函数将用于执行基本的数学运算。

calc.c

#include "calc.h"
​
int add(int a, int b) {
    return a + b;
}
​
int subtract(int a, int b) {
    return a - b;
}
​
int multiply(int a, int b) {
    return a * b;
}
​
int divide(int a, int b) {
    if (b == 0) {
        return 0;
    }
    return a / b;
}

calc.c 文件实现了 calc.h 中定义的四个函数。每个函数分别执行加、减、乘、除运算。注意,在除法运算中,我们检查了除数是否为零,以避免除零错误。

Go语言部分

main.go

package main
​
import (
    "fmt"
    "net/http"
    "github.com/gorilla/websocket"
)
​
// #cgo LDFLAGS: -L. -lcalc
// #include "calc.h"
import "C"
​
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}
​
func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("Failed to upgrade to WebSocket:", err)
        return
    }
    defer conn.Close()
​
    for {
        _, message, err := conn.ReadMessage()
        if err != nil {
            fmt.Println("Read error:", err)
            break
        }
​
        var result int
        var op string
        var a, b int
        fmt.Sscanf(string(message), "%s %d %d", &op, &a, &b)
​
        switch op {
        case "add":
            result = int(C.add(C.int(a), C.int(b)))
        case "subtract":
            result = int(C.subtract(C.int(a), C.int(b)))
        case "multiply":
            result = int(C.multiply(C.int(a), C.int(b)))
        case "divide":
            result = int(C.divide(C.int(a), C.int(b)))
        default:
            result = 0
        }
​
        err = conn.WriteMessage(websocket.TextMessage, []byte(fmt.Sprintf("%d", result)))
        if err != nil {
            fmt.Println("Write error:", err)
            break
        }
    }
}
​
func main() {
    http.HandleFunc("/ws", handleWebSocket)
    http.Handle("/", http.FileServer(http.Dir("./client")))
    fmt.Println("WebSocket server started at :8080/ws")
    fmt.Println("Static file server started at:8080")
    http.ListenAndServe(":8080", nil)
}

main.go 文件是Go语言编写的WebSocket服务器。主要功能如下:

  1. 导入必要的包:包括 fmtnet/httpgithub.com/gorilla/websocket

  2. 导入C语言库:通过 #cgo LDFLAGS#include "calc.h" 导入C语言编写的计算函数。

  3. 设置WebSocket升级器:使用 websocket.Upgrader 来处理WebSocket连接。

  4. 处理WebSocket连接:在 handleWebSocket 函数中,处理WebSocket连接的建立、消息的读取和发送。根据接收到的消息,调用相应的C语言函数进行计算,并将结果发送回客户端。

  5. 启动HTTP服务器:在 main 函数中,设置WebSocket处理函数和静态文件服务器,并启动HTTP服务器监听端口8080。

前端部分

client/index.html

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket计算器</title>
    <script>
        var socket = new WebSocket("ws://localhost:8080/ws");
​
        socket.onopen = function() {
            console.log("WebSocket connection opened");
            document.getElementById("status").innerText = "已连接";
        };
​
        socket.onmessage = function(event) {
            var result = event.data;
            document.getElementById("result").innerText = "计算结果是: " + result;
        };
​
        socket.onerror = function(error) {
            console.error("WebSocket error: " + error);
            document.getElementById("status").innerText = "错误!";
        };
​
        socket.onclose = function() {
            console.log("WebSocket connection closed");
            document.getElementById("status").innerText = "未连接!";
        };
​
        function sendOperation(op) {
            var a = document.getElementById("a").value;
            var b = document.getElementById("b").value;
​
            // 验证输入是否为数字
            if (isNaN(a) || isNaN(b)) {
                alert("请输入有效数字!");
                return;
            }
​
            socket.send(op + " " + a + " " + b);
        }
    </script>
</head>
<body>
    <h1>WebSocket计算器</h1>
    <div id="status">连接中...</div>
    <input type="number" id="a" placeholder="请输入有效数字A !">
    <input type="number" id="b" placeholder="请输入有效数字B !">
    <button onclick="sendOperation('add')">加</button>
    <button onclick="sendOperation('subtract')">减</button>
    <button onclick="sendOperation('multiply')">乘</button>
    <button onclick="sendOperation('divide')">除</button>
    <div id="result"></div>
</body>
</html>

index.html 文件是前端页面,主要功能如下:

  1. 建立WebSocket连接:通过 new WebSocket("ws://localhost:8080/ws") 建立与服务器的WebSocket连接。

  2. 处理WebSocket事件:包括连接打开、消息接收、错误处理和连接关闭事件。

  3. 发送操作:通过 sendOperation 函数,获取用户输入的两个数字,并根据用户选择的操作(加、减、乘、除)发送相应的消息到服务器。

  4. 显示结果:在接收到服务器返回的结果后,将其显示在页面上。

依赖管理

在项目目录中,运行以下命令来安装所需的Go模块依赖:

go mod tidy

这个命令会读取 go.mod 文件中的依赖声明,并自动下载这些依赖包。同时,它会生成或更新 go.sum 文件,该文件包含了依赖包的校验和,确保下载的依赖包是完整和安全的。

运行项目

1.编译C语言代码:

gcc -c calc.c -o calc.o
ar rcs libcalc.a calc.o

2.运行Go语言服务器:

go run main.go

3.访问

打开浏览器,访问链接:

​http://localhost:8080​

即可看到前端页面,输入数字并点击相应的按钮,即可进行计算。

项目在终端运行成功,会出现如下图所示的内容:

接下来我们通过浏览器访问 http://localhost:8080 ,内容如下图所示:

我们可以通过在输入框中输入需要计算的数据,再点击右侧的运算方式按钮,便可得到运算结果,如图所示:

如果觉得界面过于简陋,不好看,那么我们对这个界面进行一些调整,如下图所示:

更多优化细节请参考博主的下一篇文章!

对WebSocket计算器优化-CSDN博客对WebSocket计算器优化https://blog.csdn.net/qq_45519030/article/details/140226344

标签:WebSocket,int,C语言,result,计算器,go,http,calc
From: https://blog.csdn.net/qq_45519030/article/details/140226140

相关文章

  • C语言命名规范
    C语言命名规范在C语言中,命名规范对于代码的可读性和可维护性至关重要。以下是一些常见的C语言命名规律和建议变量命名变量名应该具有描述性,清晰地表达变量的用途或含义。变量名使用小写字母和下划线(snake_case)的组合,例如intmy_variable;。避免使用单个字符作为变量名,除非......
  • C语言字节对齐技术在嵌入式、网络与操作系统中的应用与优化
    第一部分:嵌入式系统中的字节对齐嵌入式系统通常对性能和资源有着严格的要求。在这些系统中,字节对齐的正确使用可以显著提高数据访问速度,减少内存占用,并提高系统的整体效率。一、嵌入式系统中的字节对齐挑战嵌入式系统中的微处理器和微控制器通常对数据访问的对齐有特定的要......
  • C语言笔记28 •顺序表经典算法OJ题•
    1.删除数组中指定的元素//算法实现intremoveElement(int*nums,intnumsSize,intval){   intsrc=0;//nums[src]==valsrc++   intdst=0;///nums[src]!=valsrc++ dst++   while(src<numsSize)   {      if(nums[src]==va......
  • 7.5复习C语言
    7.5复习C语言地址传参和值传参的区别1、地址传参是指将函数调用时实参的地址或指针作为形参传递给函数,函数内对形参所指向的内存空间进行操作会改变实参的值也会影响其他使用该实参的地方。2、值传参是指将函数调用时实参的值复制价给形参函数内对形参进行操作不会影响实参的值......
  • 【C语言题目】34.猜凶手
    文章目录作业标题作业内容2.解题思路3.具体代码作业标题猜凶手作业内容日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词:A说:不是我。B说:是C。C说:是D。D说:C在胡说已知3个人说了真话,1个人说的是假话。现在请......
  • 【C语言习题】33.杨氏矩阵
    文章目录作业标题作业内容2.解题思路3.具体代码作业标题杨氏矩阵作业内容有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。要求:时间复杂度小于O(N);2.解题思路我们仔细分析,不难发现,对于杨氏......
  • 【C语言习题】32.字符串旋转结果
    文章目录作业标题作业内容2.解题思路3.具体代码作业标题字符串旋转结果作业内容写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。例如:给定s1=AABCD和s2=BCDAA,返回1给定s1=abcd和s2=ACBD,返回0.AABCD左旋一个字符得到ABCDAAABCD左旋两个字......
  • 【LinuxC语言】手撕Http协议之accept_request函数实现(一)
    文章目录前言accept_request函数作用accept_request实现解析方法根据不同方法进行不同操作http服务器响应格式unimplemented函数实现总结前言在计算机网络中,HTTP协议是一种常见的应用层协议,它定义了客户端和服务器之间如何进行数据交换。在这篇文......
  • 从零开始学习嵌入式----C语言“\“字符
    C语言\01932\01\12\09的意思是什么?应该这样看:    所有的ASCII码都可以用"\"加数字(一般是八进制)来表示。而C语言中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符。     1)"\"后面如果跟了三位八进制数字就将\ddd作为......
  • C语言的简单学习
    C语言是编译型语言,先编译再运行,通常用gcc进行编译,于是安装了Ubuntu操作系统。至于编辑器,VSCode也能用,先sudoaptinstallbuild-essentialgdb,再在VSCode安装C/C++extension,就可以进行开发了。C语言程序都是 .c文件结尾,新建一个hello_world.c 文件#include<stdi......