当前位置: 首页 > ds >正文

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式

文章目录

  • 设计模式
    • 一、`socket.h` 接口(interface)
    • 二、`socket.cpp` 实现(implementation)
    • 三、`server.cpp` 使用封装(main 函数)
    • 四、`client.cpp` 使用封装(main 函数)
    • 五、退出方法
    • 六、终端输出

一、socket.h 接口(interface)

#ifndef SOCKET_H
#define SOCKET_H#include <string>
using std::string;class Socket
{
public:Socket();~Socket();bool bind(int port);bool listen(int backlog = 5);int accept();bool connect(const string &ip, int port);  // ✅ 客户端连接方法int fd() const { return m_sockfd; } // 可选:暴露 sockfd 方便客户端用private:int m_sockfd;
};#endif // SOCKET_H

二、socket.cpp 实现(implementation)

// socket.cpp
#include "socket.h"#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <cerrno>using std::string;Socket::Socket()
{m_sockfd = ::socket(AF_INET, SOCK_STREAM, 0);if (m_sockfd < 0){printf("Socket creation failed: errno=%d, errmsg=%s\n", errno, strerror(errno));}
}Socket::~Socket()
{if (m_sockfd >= 0){::close(m_sockfd);}
}bool Socket::connect(const string &ip, int port)
{sockaddr_in addr;std::memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(port);if (::inet_pton(AF_INET, ip.c_str(), &addr.sin_addr) <= 0){printf("Invalid IP address: %s\n", ip.c_str());return false;}int ret = ::connect(m_sockfd, (struct sockaddr*)&addr, sizeof(addr));if (ret < 0){printf("Connect failed: errno=%d, errmsg=%s\n", errno, strerror(errno));return false;}return true;
}void Socket::close()
{if (m_sockfd >= 0){::close(m_sockfd);m_sockfd = -1;}
}

三、server.cpp 使用封装(main 函数)

#include "socket.h"#include <iostream>
#include <unistd.h>    // read(), write()
#include <cstring>     // memsetint main()
{Socket server;if (!server.bind(8888)){std::cerr << "Failed to bind port 8888" << std::endl;return 1;}if (!server.listen()){std::cerr << "Failed to listen on port 8888" << std::endl;return 1;}std::cout << "Server listening on port 8888..." << std::endl;while (true){int client_fd = server.accept();if (client_fd < 0){continue; // accept failed}char buffer[1024];ssize_t n = ::read(client_fd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = '\0';std::cout << "Received: " << buffer << std::endl;std::string response = "Echo: ";response += buffer;::write(client_fd, response.c_str(), response.size());}::close(client_fd);}return 0;
}

四、client.cpp 使用封装(main 函数)

#include "socket.h"#include <iostream>
#include <unistd.h>     // read(), write()
#include <cstring>      // strlen()int main()
{Socket client;if (!client.connect("127.0.0.1", 8888)){std::cerr << "Failed to connect to server." << std::endl;return 1;}std::cout << "Connected to server." << std::endl;std::string input;while (true){std::cout << "Enter message: ";std::getline(std::cin, input);if (input == "exit")break;::write(client.fd(), input.c_str(), input.size());char buffer[1024];ssize_t n = ::read(client.fd(), buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = '\0';std::cout << "Server response: " << buffer << std::endl;}else{std::cout << "Server closed connection." << std::endl;break;}}return 0;
}

五、退出方法

  1. 客户端:
    当你在客户端输入:
Enter message: exit

客户端程序会退出(break 出循环)。

  1. 服务器:
    • 当前版本是永不退出的死循环
    • 你可以使用 Ctrl+C 来中断服务器进程

六、终端输出

  1. 终端 1:服务器
$ ./server
Server listening on port 8888...
Received: hello
Received: world
  1. 终端 2:客户端
$ ./client
Connected to server.
Enter message: hello
Server response: Echo: helloEnter message: world
Server response: Echo: worldEnter message: exit
http://www.xdnf.cn/news/13240.html

相关文章:

  • spring boot使用HttpServletResponse实现sse后端流式输出消息
  • Ubuntu 安装 Mysql 数据库
  • 『uniapp』消息推送 unipush的对接 支持通知消息内容客户端自定义(保姆级图文)
  • STL 2迭代器
  • rknn toolkit2搭建和推理
  • DL00871-基于深度学习YOLOv11的盲人障碍物目标检测含完整数据集
  • C++11作用域枚举(Scoped Enums):从入门到精通
  • AI书签管理工具开发全记录(十九):嵌入资源处理
  • 自然语言处理——Transformer
  • LTR-381RGB-01RGB+环境光检测应用场景及客户类型主要有哪些?
  • Android15默认授权浮窗权限
  • 驭码CodeRider 2.0全栈开发实战指南:从零构建现代化电商平台
  • 【若依】框架项目部署笔记
  • LabVIEW双光子成像系统技术
  • 力扣热题100 k个一组反转链表题解
  • 由于 z(x,y) 的变化导致的影响(那部分被分给了链式项)
  • 实现自动化管理、智能控制、运行服务的智慧能源开源了。
  • Spring MVC执行流程简介
  • rnn判断string中第一次出现a的下标
  • ESP32开发之WS2812B控制
  • 前端性能优化-虚拟滚轮(Virtual Scroll)
  • nuclio
  • Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
  • [拓扑优化] 1.概述
  • 【http解析——三个版本对比】
  • 【Qt】控件 QWidget
  • 解决Excel词典(xllex.dll)文件丢失或损坏问题的终极指南:从基础到高级修复技巧
  • Netty
  • 嵌入式学习之系统编程(八)IPC、管道(有名与无名)和信号通信(6.3)
  • Python 训练 day46