52.TcpSocket

lesson40 聊天室改成多线程

线程池内部处理任务时候已经解锁了,所以函数中成员集不属于临界资源,多线程访问会出现问题

可以把route新增,转发,删除在udpserver拆开,这样的话锁的力度就变细了。

看网络第二个课件的补充参考部分 改一下Inetaddr.hpp 主机转网络封装好了之后,sockaddr_in就不需要初始化各种值,肢解创建InetAddr,直接就初始化好了。

inet_ntoa有可能存在线程安全问题 ip以后用inet_ntop inet_pton 端口用ntohs htons

windows linux能联动

看tcpechoserver代码

服务器禁止拷贝

继承之后如果想拷贝,必须拷贝父类,父类禁止拷贝所以就禁止拷贝

telnet 可以远程连接tcp服务器 telnet ip 端口号

cpp 复制代码
#pragma once

// 注意:基于截图内容,省略了外部头文件(如 <iostream>, <unistd.h>, "Log.hpp", "InetAddr.hpp" 等)
// 假设 backlog 和 CONV 宏已在 Common.hpp 等文件中定义
// const static int backlog = 16;
// #define CONV(addr) (struct sockaddr *)&(addr)

// 服务器往往是禁止拷贝的
using namespace LogModule;

const static int defaultsockfd = -1;

class TcpServer : public NoCopy
{
public:
    TcpServer(uint16_t port) : _port(port), _listensockfd(defaultsockfd), _isrunning(false)
    {}

    void Init()
    {
        // 1. 创建套接字文件
        _listensockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listensockfd < 0)
        {
            LOG(LogLevel::FATAL) << "socket error";
            exit(SOCKET_ERR);
        }
        LOG(LogLevel::INFO) << "socket success: " << _listensockfd; // 3

        // 2. bind众所周知的端口号
        InetAddr local(_port);
        int n = bind(_listensockfd, local.NetAddrPtr(), local.NetAddrLen());
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "bind error";
            exit(BIND_ERR);
        }
        LOG(LogLevel::INFO) << "bind success: " << _listensockfd; // 3

        // 3. 设置socket状态为listen
        n = listen(_listensockfd, backlog);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "listen error";
            exit(LISTEN_ERR);
        }
        LOG(LogLevel::INFO) << "listen success: " << _listensockfd; // 3
    }

    void Service(int sockfd, InetAddr &peer)
    {
        char buffer[1024];
        while (true)
        {
            // 1. 先读取数据
            // a. n>0: 读取成功
            // b. n<0: 读取失败
            // c. n==0: 对端把链接关闭了,读到了文件的结尾 --- pipe
            ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
            if (n > 0)
            {
                buffer[n] = 0; // 设置为C风格字符串,n<= sizeof(buffer)-1
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " say# " << buffer;
                
                // 2. 写回数据
                std::string echo_string = "echo# ";
                echo_string += buffer;

                write(sockfd, echo_string.c_str(), echo_string.size());
            }
            else if (n == 0)
            {
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " 退出了...";
                close(sockfd);
                break;
            }
            else
            {
                LOG(LogLevel::DEBUG) << peer.StringAddr() << " 退出了...";
                close(sockfd);
                break;
            }
        }
    }

    void Run()
    {
        _isrunning = true;
        while (_isrunning)
        {
            // a. 获取链接
            struct sockaddr_in peer;
            socklen_t len = sizeof(sockaddr_in);
            // 如果没有连接,accept就会阻塞
            int sockfd = accept(_listensockfd, CONV(peer), &len);
            if (sockfd < 0)
            {
                LOG(LogLevel::WARNING) << "accept error";
                continue;
            }
            InetAddr addr(peer);
            LOG(LogLevel::INFO) << "accept success, peer addr : " << addr.StringAddr();

            // version0 -- test version --- 单进程程序 --- 不会存在的!
            Service(sockfd, addr);
        }
        _isrunning = false;
    }

    ~TcpServer()
    {
    }

private:
    uint16_t _port;
    int _listensockfd; // 监听socket
    bool _isrunning;
};

相关推荐
сокол1 小时前
【网安-Web渗透测试-内网渗透】内网横向移动——IPC连接
服务器·windows·网络安全·系统安全
剑神一笑1 小时前
Linux xargs 命令深度解析:从管道到命令构建的桥梁
linux·运维·chrome
QH139292318801 小时前
罗德与施瓦茨 FSW26 FSW43 FSW50高端信号分析仪
网络·功能测试·单元测试·集成测试·模块测试
白山云北诗2 小时前
零成本/低成本!个人站长DDoS防护实战方案
网络·安全·ddos
jimy12 小时前
Oracle的always free账户,提高网络使用率的保活脚本
服务器·网络·oracle
一渊之隔2 小时前
uniapp蓝牙搜索连接展示蓝牙设备包含信号显示
前端·网络·uni-app·bluetooth
xhbh6662 小时前
TCP端口转发不生效?IP转发、防火墙、SELinux排查手册
服务器·ip·端口流量转发·路由端口转发·ip隐藏·tcp 端口转发
xhbh6662 小时前
Windows网络转发如何配置?netsh命令完整指南
服务器·网络·windows·ip·端口流量转发·路由端口转发·ip隐藏
量子炒饭大师2 小时前
【Linux系统编程】Cyberpunk在霓虹丛林中构建堡垒 ——【关于shell命令及其运行原理】
linux·运维·服务器·shell