Socket编程实验

文章目录

      • 服务端:
      • 客户端:
      • 使用说明:
      • 封装后服务端:
      • 封装后客户端

听学弟学妹们反馈,好像老师发的socket编程实验指导里的代码跑不起来。
今天花了一大把时间写了下socket编程代码
现在附上能跑的c++代码:
最重要的是,记得更改其中注释和变量名,不然的话容易被老师查重,一定要改
(后面有使用说明!)

服务端:

#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cerr << "WSAStartup failed with error: " << result << std::endl;
        return 1;
    }


    // 创建 Socket
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "socket failed with error: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // 绑定端口
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(8080);
    result = bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
    if (result == SOCKET_ERROR) {
        std::cerr << "bind failed with error: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    // 监听连接
    result = listen(serverSocket, SOMAXCONN);
    if (result == SOCKET_ERROR) {
        std::cerr << "listen failed with error: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Server is listening on port 8080..." << std::endl;

    // 接受客户端连接
    SOCKET clientSocket = accept(serverSocket, NULL, NULL);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "accept failed with error: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Client connected." << std::endl;
    while (true) {
        // 接收客户端发送的数据并打印
        char buffer[1024];
        result = recv(clientSocket, buffer, sizeof(buffer), 0);
        if (result > 0) {
            buffer[result] = '\0';
            std::cout << "收到消息: " << buffer << std::endl;
            const char* feedback = "服务端已经收到消息";
            int result2 = send(clientSocket, feedback, strlen(feedback), 0);
            if (result2 == SOCKET_ERROR) {
                std::cerr << "返回消息报错 " << WSAGetLastError() << std::endl;
            }
        }
        else if (result == 0) {
            std::cout << "客户端已关闭." << std::endl;
            break;
        }
        else {
            std::cerr << "recv failed with error: " << WSAGetLastError() << std::endl;
            break;
        }
    }
    // 关闭 Socket
    closesocket(clientSocket);
    closesocket(serverSocket);


    WSACleanup();

    return 0;
}


客户端:

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h> // 包含 InetPton 函数的声明
#include <string>

#pragma comment(lib, "ws2_32.lib")

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cerr << "WSAStartup failed with error: " << result << std::endl;
        return 1;
    }

    // 创建 Socket
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "socket failed with error: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // 连接到服务端
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr); // 将字符串转换为网络地址
    serverAddr.sin_port = htons(8080); // 服务端端口
    result = connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
    if (result == SOCKET_ERROR) {
        std::cerr << "connect failed with error: " << WSAGetLastError() << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Connected to server." << std::endl;
    std::cout << "已经成功链接到服务端" << std::endl;

    // 输入消息并发送到服务端
    std::cout << "请输入发送到服务端的信息 (发送 exit 则断开链接):" << std::endl;
    std::string message;
    while (true) {
        std::getline(std::cin, message);
        if (message == "exit") {
            break;
        }
        result = send(clientSocket, message.c_str(), message.length(), 0);
        if (result == SOCKET_ERROR) {
            std::cerr << "send failed with error: " << WSAGetLastError() << std::endl;
            closesocket(clientSocket);
            WSACleanup();
            return 1;
        }
        // 接收服务端的反馈信息
        char buffer[1024];
        result = recv(clientSocket, buffer, sizeof(buffer), 0);
        if (result > 0) {
            buffer[result] = '\0';
            std::cout << "发送成功: " << buffer << std::endl;
        }
        else if (result == 0) {
            std::cout << "服务端连接关闭" << std::endl;
        }
        else {
            std::cerr << "出错了: " << WSAGetLastError() << std::endl;
        }
    }

    std::cout << "Message sent to server." << std::endl;




    // 关闭 Socket
    closesocket(clientSocket);
    WSACleanup();

    return 0;
}


使用说明:

1,这个程序得用visual studio来运行,就是这个:
在这里插入图片描述
2, 你要建2个项目
步骤:
(1)
在这里插入图片描述
(2)
在这里插入图片描述
(3)
在这里插入图片描述
(4)
在这里插入图片描述
(5)
重复以上(1)~(4)步骤
这样你就得到了两个项目,往这两个项目的cpp文件中分别复制粘贴服务端代码和客户端代码。
最后先运行服务端,再运行客户端
就可以把客户端信息发送到服务端了。
重要的是,记得更改其中注释和变量名,不然的话容易被老师查重

后面的代码就是我封装了以后的服务端与客户端。
服务端里使用了多线程进行处理信息,
客户端有连接设置,连不上会自动重连。
欢迎扩展,拿去改改当轮子用

封装后服务端:

#include <iostream>
#include <winsock2.h>
#include <thread>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

class MyServer {
public:
    MyServer() {
        init(); //先初始化Winsock
        createServerSocket();   //创建Socket服务端
    }
    //设置端口
    int setPort(int ppot) {
        port = ppot;
        return 0;
    }
    //创建套接字
    int setServerBind() {
        //在服务端创建一个套接字,并将其绑定到指定的 IP 地址和端口号上,以便服务端能够监听客户端的连接请求
        serverAddr.sin_family = AF_INET;    //设置地址族为AF_INET.即IPv4地址
        serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); //将IP地址设置为INADDR_ANY 表示可以接收来自任何可用接口的连接请求
        serverAddr.sin_port = htons(port);  //设置端口号,表示服务端将在port端口上监听连接请求

        //将服务端套接字绑定在指定地址上。
        int result = bind(*serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));

        if (result == SOCKET_ERROR) {
            std::cerr << "bind failed with error: " << WSAGetLastError() << std::endl;
            closesocket(*serverSocket);
            WSACleanup();
            return 1;
        }


        return 0;
    }

    //设置监听连接
    int listenPost() {
        // 监听连接
        int result = listen(*serverSocket, SOMAXCONN);
        if (result == SOCKET_ERROR) {
            std::cerr << "listen failed with error: " << WSAGetLastError() << std::endl;
            closesocket(*serverSocket);
            WSACleanup();
            return 1;
        }

        std::cout << "服务端正在监视端口" << port << std::endl;
        return 0;
    }

    //处理连接
    int disposeConnect() {
        while (true) {
            SOCKET clientSocket = accept(*serverSocket, NULL, NULL);
            if (clientSocket == INVALID_SOCKET) {
                std::cerr << "出问题了: " << WSAGetLastError() << std::endl;
                closesocket(*serverSocket);
                WSACleanup();
                return 1;
            }

            // 创建线程处理连接
            std::thread clientThread(&MyServer::HandleClient, this, clientSocket);
            clientThread.detach(); // 在后台运行线程,不阻塞主线程
        }
        return 0;
    }

    //关闭套接字
    int closeServer() {
        closesocket(*serverSocket);
        WSACleanup();
        return 0;
    }

    ~MyServer() {

    }

private:
    //初始化Winsock
    int init() {
        std::cout << "正在初始化Winsock" << std::endl;
        int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (result != 0) {
            std::cerr << "WSAStartup运行失败,报错: " << result << std::endl;
            return 1;
        }
        std::cout << "初始化成功" << std::endl;
        return 0;
    }

    //创建Socket服务端
    int createServerSocket() {
        std::cout << "正在创建Socket服务端" << std::endl;
        serverSocket = new SOCKET(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
        if (*serverSocket == INVALID_SOCKET) {
            // 判断是否创建成功
            std::cerr << "socket服务端创建失败,报错: " << WSAGetLastError() << std::endl;
            WSACleanup();
            return 1;
        }
        std::cout << "创建成功" << std::endl;
        return 0;
    }

    //处理单个客户端连接
    void HandleClient(SOCKET client) {
        sockaddr_in clientAddr;
        int addrLen = sizeof(clientAddr);
        getpeername(client, (SOCKADDR*)&clientAddr, &addrLen);
        char clientIP[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &(clientAddr.sin_addr), clientIP, INET_ADDRSTRLEN);
        std::cout << "来自" << clientIP << ":" << ntohs(clientAddr.sin_port) << "的连接" << std::endl;
        while (true) {
            char buffer[1024];
            int result = recv(client, buffer, sizeof(buffer), 0);
            if (result > 0) {
                buffer[result] = '\0';
                std::cout << clientIP << ":" << ntohs(clientAddr.sin_port) << ": " << buffer << std::endl;

                const char* feedback = "Message received by server.";
                int result2 = send(client, feedback, strlen(feedback), 0);
                if (result2 == SOCKET_ERROR) {
                    std::cerr << "send failed with error: " << WSAGetLastError() << std::endl;
                }
            }
            else if (result == 0) {
                std::cout << clientIP << ":" << ntohs(clientAddr.sin_port) << ": ""连接关闭." << std::endl;
                break;
            }
            else {
                std::cerr << clientIP << ":" << ntohs(clientAddr.sin_port) << ": ""错误: " << WSAGetLastError() << std::endl;
                break;
            }
        }
        closesocket(client);
    }


    SOCKET* serverSocket;    //Socket服务端
    int port = 8080;         // 端口号
    sockaddr_in serverAddr;  //服务端地址信息
    WSADATA wsaData;        //

};

int main() {

    MyServer* server = new MyServer();
    /*int pot;*/
    /*std::cout << "请输入端口:";
    std::cin >> pot;*/
    server->setServerBind();
    server->listenPost();
    server->disposeConnect();
    server->closeServer();


    return 0;
}

封装后客户端

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h> // 包含 InetPton 函数的声明
#include <string>
#include <thread>

#pragma comment(lib, "ws2_32.lib")

class MyClient {
public:
    MyClient() {
        init();
        createClientSocket();
    }

    //设置目标IP
    int setAimIp(char* ip) {

        aimIp = ip;
        return 0;
    }

    //设置目标端口
    int setAimPort(int pot) {
        aimPort = pot;
        return 0;
    }

    //连接服务端
    int ConnectServer() {
        while (1) {
            sockaddr_in serverAddr;
            serverAddr.sin_family = AF_INET;
            inet_pton(AF_INET, aimIp, &serverAddr.sin_addr); // 将字符串转换为网络地址
            std::cout << "目标:" << aimIp << ":" << aimPort << std::endl;
            serverAddr.sin_port = htons(aimPort); // 服务端端口
            int result = connect(*clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
            if (result == SOCKET_ERROR) {
                std::cerr << "connect failed with error: " << WSAGetLastError() << std::endl;
                std::cout << "Waiting for server to start..." << std::endl;
                std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待5秒
                continue; // 继续尝试重新连接
            }


            std::cout << "已经成功链接到服务端" << aimIp << ":" << aimPort << std::endl;
            break;
        }
        return 0;
    }
    //发送信息
    int sendMessage(char* message) {
        int result = send(*clientSocket, message, sizeof(message), 0);
        if (result == SOCKET_ERROR) {
            std::cerr << "发送失败: " << WSAGetLastError() << std::endl;
            closesocket(*clientSocket);
            WSACleanup();
            return 1;
        }
        // 接收服务端的反馈信息
        char buffer[1024];
        result = recv(*clientSocket, buffer, sizeof(buffer), 0);
        if (result > 0) {
            buffer[result] = '\0';
            std::cout << "发送成功: " << buffer << std::endl;
        }
        else if (result == 0) {
            std::cout << "服务端连接关闭" << std::endl;
        }
        else {
            std::cerr << "出错了: " << WSAGetLastError() << std::endl;
        }
        return 0;
    }

    //关闭客户端
    int closeClient() {
        closesocket(*clientSocket);

        return 0;
    }

    ~MyClient() {
        WSACleanup();
    }


private:
    //初始化
    int init() {
        int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (result != 0) {
            std::cerr << "WSAStartup failed with error: " << result << std::endl;
            return 1;
        }
        return 0;
    }

    //创建客户端
    int createClientSocket() {
        std::cout << "正在创建Socket客户端" << std::endl;
        clientSocket = new SOCKET(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
        if (*clientSocket == INVALID_SOCKET) {
            std::cerr << "ocket客户端创建失败,报错:" << WSAGetLastError() << std::endl;
            WSACleanup();
            return 1;
        }
        std::cout << "创建成功" << std::endl;
        return 0;
    }

    WSADATA wsaData;
    SOCKET* clientSocket;
    char* aimIp;
    int aimPort;

};

int main() {
    MyClient* client = new MyClient();

    char ip[] = "127.0.0.1";
    int port = 8080;
    client->setAimIp(ip);   //设置ip
    client->setAimPort(port);   //设置端口
    client->ConnectServer();//连接服务器

    // 输入消息并发送到服务端
    std::cout << "请输入发送到服务端的信息 (发送 exit 则断开链接):" << std::endl;
    char* message = new char[1024];
    while (true) {
        std::cin.getline(message, 1024);
        if (!strcmp(message, "exit")) {
            break;
        }
        client->sendMessage(message);
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/574873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nosql数据库 redis

一、介绍 1、redis与mysql的区别&#xff1a; Redis是一种基于键值对的内存数据库&#xff0c;数据存储在内存中&#xff0c;因此读写速度非常快。它支持多种数据结构&#xff0c;如字符串、哈希、列表等。 MySQL是一种关系型数据库&#xff0c;数据以表格的形式组织存储在磁…

12.6.1 实验5:IOS恢复

1、实验目的 通过本实验可以掌握&#xff1a; copy方式恢复IOS的步骤。TFTPDNLD方式恢复IOS的步骤。Xmodem方式恢复IOS的步骤。 2、实验拓扑 路由器IOS恢复的实验拓扑如下图所示。 3、实验步骤 如果工作中不慎误删除路由器IOS&#xff0c;或者升级了错误版本的IOS&#xff…

Sylar C++高性能服务器学习记录06 【线程模块-代码分析篇】

早在19年5月就在某站上看到sylar的视频了&#xff0c;一直认为这是一个非常不错的视频&#xff0c;还有幸加了sylar本人的wx&#xff0c;由于本人一直是自学编程&#xff0c;基础不扎实&#xff0c;也没有任何人的督促&#xff0c;没能坚持下去&#xff0c;每每想起倍感惋惜。恰…

机器学习day3

一、距离度量 1.欧氏距离 2.曼哈顿距离 3.切比雪夫距离 4.闵可夫斯基距离 二、特征与处理 1.数据归一化 数据归一化是一种将数据按比例缩放&#xff0c;使之落入一个小的特定区间的过程。 代码实战 运行结果 2.数据标准化 数据标准化是将数据按照其均值和标准差进行缩放的过…

2024最新版JavaScript逆向爬虫教程-------基础篇之面向对象

目录 一、概念二、对象的创建和操作2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承3.3.1 对象的原型式继承3.3.2 …

paddle ocr v4 微调训练文字识别模型实践

识别步骤参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/recognition.md 微调步骤参考:https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.7.1/doc/doc_ch/finetune.md 训练必要性 原始模型标点符号和括号容易识别不到 数据准备…

【漏洞复现】Weblogic 任意文件上传漏洞(CVE-2018-2894)

漏洞简介 Oracle在7月更新中&#xff0c;修复了Weblogic Web Service Test Page中一处任意文件上传漏洞&#xff0c;Web Service Test Page在"生产模式"下默认不开启&#xff0c;所以该漏洞有一定限制&#xff0c;利用该漏洞&#xff0c;可以上传任意.jsp文件&#x…

用Redis实现获取验证码,外加安全策略

安全策略 一小时内只能获取三次&#xff0c;一天内只能获取五次 Redis存储结构 代码展示 import cn.hutool.core.util.RandomUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.Test; import org.spri…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

RK3588 - RKNN(Rockchip 神经处理单元)的逆向工程

本文翻译自https://jas-hacks.blogspot.com/2024/02/rk3588-reverse-engineering-rknn.html RK3588 NPU 的内部操作和功能主要隐藏在名为RKNPU2的闭源 SDK 中。由于对大型语言模型 (LLM) 的兴趣以及对transform模型最佳矩阵乘法的追求&#xff0c;想了解 RKNPU SDK 新引入的矩阵…

值得让英伟达CEO黄仁勋亲自给OpenAI配送的AI服务器!一文带你了解算力,GPU,CPU!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

【C++】双指针算法:和为s的两个数字

1.题目 虽然在牛客上是个中等题&#xff0c;但我感觉是比较简单的。大家在看完这篇文章后可以看看我的上一篇文章&#xff1a;有效三角形的个数。本文章的题目的解法只是有效三角形的个数这道题目的一个环节。看懂这篇文章后可以更好的解决有效三角形个数那道题目&#xff01; …

电力系统IEC-104报文主要常用详解

文章目录 1️⃣ IEC-1041.1 前言1.2 报文分类1.3 U帧报文1.3.1 常见报文1.3.1 报文解析 1.4 S帧报文1.4.1 说明1.4.2 报文解析 1.5 I帧报文1.5.1 报文解析 1.6 控制域I帧报文S帧报文U帧报文介绍 1.7 ASDU1.7.1 常见类型标识1.7.2 常见结构限定词1.7.3 常见传送原因1.7.4 信息体…

艾瑞泽5汽车电子控制单元CAN通信数据读写车辆网络系统交互接口

艾瑞泽5的网关接口数据交换通常涉及车辆内部电子设备之间的信息传输&#xff0c;包括车身系统、娱乐系统、远程控制、车辆状态监控、CAN数据采集分析、整车DBC控制策略等信息。 艾瑞泽5作为一款采用CAN协议的汽车&#xff0c;其CAN通信的开发可以提高车辆的安全性、可靠性和实…

Visual Studio Code使用

目录 1.python的调试 2.c的运行 方法1&#xff1a; 方法2&#xff1a; 3.c的调试 3.1调试方法一&#xff1a;先生成执行文件&#xff0c;再调试 3.2调试方法二&#xff1a;同时生成执行文件&#xff0c;调试 4.tasks.json 与launch.json文件的参考 4.1C生成执行文件tas…

uniapp H5实现签名

第一种&#xff1a;跳转签名页面 1、创建审核页面audit.vue <template><view><uni-section title""><view class"auditClass"><uni-forms :model"baseFormData" ref"baseFormRef" :rules"rules&quo…

数据结构初阶——树和二叉树

数据结构初阶——树和二叉树 1. 树的概念和结构1.1 树的概念1.2 树的表示 2. 二叉树2.1 二叉树的概念和结构2.2 二叉树的存储结构2.2.1 顺序存储2.2.2 链式存储 3. 二叉树的顺序结构及实现——堆3.1 堆的概念和结构3.2 堆的实现3.2.1 堆的定义3.2.2 堆的向上调整3.2.3 堆的向下…

【网络安全】安全事件管理处置 — 事件分级分类

专栏文章索引&#xff1a;网络安全 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、安全事件分级 二、应急事件分级 三、安全事件分类 四、常见安全事件原因分析 1.web入侵 2.漏洞攻击 3.网络攻击 一、安全事件分级 在对安全事件的应急响应过程中&#xf…

【Hadoop】-Apache Hive概述 Hive架构[11]

目录 Apache Hive概述 一、分布式SQL计算-Hive 二、为什么使用Hive Hive架构 一、Hive组件 Apache Hive概述 Apache Hive是一个在Hadoop上构建的数据仓库基础设施&#xff0c;它提供了一个SQL-Like查询语言来分析和查询大规模的数据集。Hive将结构化查询语言&#xff08;…

LT8711UXD助力新款Swtich游戏机底座《4K/60HZ投屏方案》

Nintendo Switch&#xff08;OLED版&#xff09;正面搭载了一块分辨率为720P的7.0英寸OLED屏幕&#xff1b;具有白色和电光蓝电光红2种颜色&#xff1b;机身长度102毫米&#xff0c;宽度242毫米&#xff0c;厚度13.9毫米&#xff0c;重量约420克。 [2]Nintendo Switch&#xff…