C++ TCP通信服务端

发两篇文章水一水,拿点积分

非计算机专业,只是有需要临时学习的,大佬轻喷

头文件"TCPServer.h"

///
//  
//  TCP通信,服务端
//                                                     ------ design by karaoit
///

#pragma once
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")

#define IP "127.0.0.1"
#define Htons 65432
//宏定义
#ifndef _TCPSERVER_H
#define _TCPSERVER_H


class TCPServer {

/**
    @brief:构造函数,每次创建类的新对象时执行
    @param:无
    @note:无
    @retval:无
  */
public: TCPServer();

/**
    @brief:析构函数,每次删除所创建的对象时执行
    @param:无
    @note:无
    @retval:无
  */
public: ~TCPServer();



private: WSADATA wsaData;                            //存储winsock初始化数据
private: SOCKET serverSocket, clientSocket;          //套接字
private: struct sockaddr_in serverAddr, clientAddr;  //定义两个结构体,用于存储服务器和客户端的地址信息
private: int addrLen = sizeof(clientAddr);           //定义地址结构的长度
private: char buffer[1024] = { 0 };                  //用于存储接收和发送的数据

/**
    @brief:构建TCP通信服务端,初始化TCP配置
    @param:无
    @note:无
    @retval:0 表示成功构建服务端, -1表示异常退出
  */
public: int TCPServerInit(void);

/**
    @brief:向客户端发送信息
    @param:无
    @note:测试用代码
    @retval:无
  */
public: void SendInfo(void);

/**
    @brief:接收来自客户端的信息
    @param:无
    @note:测试用代码
    @retval:无
  */
public: void ReceiveInfo(void);

/**
    @brief:关闭服务端
    @param:无
    @note:无
    @retval:无
  */
public: void TCPServerCloss(void);
// 关闭套接字
    closesocket(clientSocket);
    closesocket(serverSocket);
    WSACleanup();
};


#endif // !_TCPSERVER_H

代码详解:

需要引入的库:

    • winsock2.hws2tcpip.h 是Windows socket API的必要头文件。
    • iostreamstring 用于输入输出和字符串操作。
  • #pragma comment(lib, "ws2_32.lib") 指示链接器链接Winsock库。

宏定义:

        #define IP "127.0.0.1" 

        回环地址,指向本机,若想要与其他主机通信需改为对应IP地址


        #define Htons 65432    

        端口号,服务端与客户端端口号需保持一致

源文件"TCPServer.cpp"

///
//  
//  TCP通信,服务端
//                                                  ------ design by Karaoit
///

#include "TCPServer.h"
#include <iostream>

TCPServer::TCPServer() {
	std::cout << "TCPServer Create" << std::endl;
}


TCPServer::~TCPServer() {
    std::cout << "TCPServer Delete" << std::endl;
}

int TCPServer::TCPServerInit(void) {
    // 初始化Winsock
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    // 创建套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "Unable to create socket" << std::endl;
    }
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(65432);
    // 绑定套接字
    bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    // 开始监听
    listen(serverSocket, 3);
    std::cout << "服务器正在监听:65432..." << std::endl;
    // 接受连接
    clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &addrLen);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Accept failed" << std::endl;
        return -1;
    }
    return 0;
}

void TCPServer::SendInfo(void) {
    std::string response;
    std::cout << "请输入要发送的消息: ";
    std::getline(std::cin, response);
    send(clientSocket, response.c_str(), response.length(), 0);
}

void TCPServer::ReceiveInfo(void) {
    int valread = recv(clientSocket, buffer, sizeof(buffer), 0);
    if (valread > 0) {
        std::cout << "收到消息: " << buffer << std::endl;
        // 清空缓冲区
        memset(buffer, 0, sizeof(buffer));
    }
}

void TCPServer::SendInfo(std::string message) {
    std::cout << "发送消息: " << message << std::endl;
    send(clientSocket, message.c_str(), message.length(), 0);
}


void TCPServer::SendInfo(int value) {
    std::string message;
    message = std::to_string(value);
    std::cout << "发送数据:" << value << std::endl;
    send(clientSocket, message.c_str(), message.length(), 0);
}

void TCPServer::TCPServerCloss(void) {
    // 关闭套接字
    closesocket(clientSocket);
    closesocket(serverSocket);
    WSACleanup();
}

代码详解:

TCPServer::TCPServerInit(void)

        WSAStartup(MAKEWORD(2, 2), &wsaData);

        WSAStartup函数用于初始化Winsock库,这是Windows下进行网络编程的基础库。MAKEWORD(2, 2)指定使用的Winsock版本是2.2

        serverSocket = socket(AF_INET, SOCK_STREAM, 0);

        socket函数用于创建一个套接字(socket)。AF_INET表示使用IPv4地址,SOCK_STREAM表示使用TCP协议。创建成功后,serverSocket变量将被赋值为新创建的套接字句柄

        bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

  bind函数将创建的套接字与指定的地址结构绑定,这样网络上的数据包就能正确转发到该套接字。

        listen(serverSocket, 3);

        listen函数让套接字进入监听状态,等待客户端的连接请求。这里的第一个参数是要监听的套接字,第二个参数指定了允许的待处理连接的最大数量

TCPServer::SendInfo(void)

        send(clientSocket, response.c_str(), response.length(), 0);

        send函数用于向已连接的客户端发送消息。参数说明:

  • clientSocket是之前接受连接时获得的套接字句柄,指定了要发送数据的目标客户端
  • response.c_str()返回指向response字符串数据的指针,将其转换为C风格字符串(const char*类型),这是send函数所需的格式
  • response.length()获取消息的长度
  • 最后一个参数0表示使用默认的发送选项

TCPServer::ReceiveInfo(void)

        int valread = recv(clientSocket, buffer, sizeof(buffer), 0);
  • clientSocket 是当前与客户端连接的套接字句柄。
  • buffer 是一个字符数组(通常是一个 char 类型的数组)用于存储接收到的数据。
  • sizeof(buffer) 指定了要读取的最大字节数,也就是 buffer 的大小。
  • 最后一个参数 0 表示使用默认的接收选项。
        memset(buffer, 0, sizeof(buffer));

        使用 memset 函数清空 buffer,将其所有字节设为 0。这样做是为了在下次接收消息前确保 buffer 是空的,避免输出重复的旧数据。

主函数

#include "TCPServer.h"

int main() {
	TCPServer tcp;
	while (tcp.TCPServerInit() != 0);
	while (true) {
		tcp.ReceiveInfo();
		tcp.SendInfo();
	}
    tcp.TCPServerCloss();
    tcp.~TCPServer();
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值