C++小工具封装 —— NetWork(TCP、UDP)

server/2024/12/18 23:31:59/

       在之前的文章中我们介绍到也写到基于TCP和UDP协议的网络通信。本篇我们又闲得无聊把这俩给封装成一个小工具以满足实际应用时多功能网络服务器的需要。

        这个NetWork小工具是在Windows下制作的所以别忘了该有的头文件。C++中编写我们就遵循面向对象的思想来。

#ifndef NETWORK_H
#define NETWORK_H#include <iostream>
#include <sys/types.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>class NetWork
{int sock;           //socket对象描述符int type;           //协议类型sockaddr_in addr;   //通信地址socklen_t addrlen;  //地址结构字节数bool is_svr;        //是否为服务器端
public:NetWork(void);NetWork(int type,const char *ip,short port,bool is_svr=false);~NetWork(void);bool open(void);NetWork* accept(void);int send(const char *buf,int flag=0);int send(const void *buf,size_t len,int flag=0);int recv(void *buf,size_t len,int flag=0);
};#endif // NETWORK_H

这里我们要特别注意,在Linux和Windows下进行网络编程包含的头文件有所区别,如下注释掉的是Linux下所包含的头文件,Windows下编程需要加上下面三行头文件:

// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>

接着来完成定义:

#include "network.h"
using namespace std;NetWork::NetWork(void)
{addrlen = sizeof(addr);type = SOCK_STREAM;is_svr = false;
}NetWork::NetWork(int type, const char *ip, short port, bool is_svr):type(type), is_svr(is_svr)
{// 不在构造函数中创建socket,因为socket创建可能失败,而构造函数是没有返回值的,不能在此创建addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip);addrlen = sizeof(addr);
}NetWork::~NetWork(void)
{close(sock);
}bool NetWork::open(void)
{WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){perror("WSADATA失败");}//创建socket对象sock = socket(AF_INET, type, 0);if (sock < 0){perror("socket");return false;}//根据type和is_svr执行以下流程if(is_svr){if(bind(sock, (sockaddr*)&addr, addrlen)){perror("bind");return false;}if(SOCK_STREAM == type && listen(sock, 50)){perror("listen");return false;}}else if(SOCK_STREAM == type && connect(sock, (sockaddr*)&addr, addrlen)){perror("connect");return false;}return true;
}NetWork *NetWork::accept(void) 
{if(SOCK_STREAM!= type || !is_svr){puts("只有type为SOCK_STREAM且为服务端才能调用该函数\n");return NULL;}NetWork *nw = new NetWork;nw->sock = ::accept(sock, (sockaddr*)&nw->addr, &nw->addrlen);if(nw->sock < 0){perror("accept");delete nw;return NULL;}return nw;
}int NetWork::send(const char *buf, int flag) 
{if(SOCK_STREAM == type)return ::send(sock, buf, strlen(buf)+1, flag);elsereturn sendto(sock, buf, strlen(buf)+1, flag, (sockaddr*)&addr, addrlen);
}int NetWork::send(const void *buf, size_t len, int flag) 
{if(SOCK_STREAM == type)return ::send(sock, (const char*)buf, len, flag);elsereturn sendto(sock, (const char*)buf, len, flag, (sockaddr*)&addr, addrlen);
}int NetWork::recv(void *buf, size_t len, int flag) 
{if(SOCK_STREAM == type)return ::recv(sock, (char*)buf, len, flag);elsereturn recvfrom(sock, (char*)buf, len, flag, (sockaddr*)&addr, &addrlen);
}

细心的你应该可以发现,我们Windows下写的函数定义好像和上一篇Linux下写的有点区别:

WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{perror("WSADATA失败");
}

可以发现,我们在创建socket套接字之前有这么几行陌生的代码。这段代码的作用是初始化 Windows Socket API。在使用网络编程之前,需要先调用 WSAStartup 来初始化 Winsock DLL。

over


http://www.ppmy.cn/server/151289.html

相关文章

开源分布式系统追踪-03-CNCF jaeger-02-快速开始

分布式跟踪系列 CAT cat monitor 分布式监控 CAT-是什么&#xff1f; cat monitor-02-分布式监控 CAT埋点 cat monitor-03-深度剖析开源分布式监控CAT cat monitor-04-cat 服务端部署实战 cat monitor-05-cat 客户端集成实战 cat monitor-06-cat 消息存储 skywalking …

TQ15EG开发板教程:使用SSH登录petalinux

本例程在上一章“创建运行petalinux2019.1”基础上进行&#xff0c;本例程将实现使用SSH登录petalinux。 将上一章生成的BOOT.BIN与imag.ub文件放入到SD卡中启动。给开发板插入电源与串口&#xff0c;注意串口插入后会识别出两个串口号&#xff0c;都需要打开&#xff0c;查看串…

【计算机视觉】医疗图像关键点识别

1. CNN 1.1. 设备参数 1.2. 代码 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader from torchvision import transforms from tqdm import tqdm import os import cv2 import numpy as np import time im…

什么是正则化?Regularization: The Stabilizer of Machine Learning Models(中英双语)

正则化&#xff1a;机器学习模型的稳定器 1. 什么是正则化&#xff1f; 正则化&#xff08;Regularization&#xff09;是一种在机器学习模型训练中&#xff0c;通过约束模型复杂性以防止过拟合的技术。 它的核心目标是让模型不仅在训练集上表现良好&#xff0c;还能在测试集上…

通过ajax的jsonp方式实现跨域访问,并处理响应

一、场景描述 现有一个项目A&#xff0c;需要请求项目B的某个接口&#xff0c;并根据B接口响应结果A处理后续逻辑。 二、具体实现 1、前端 前端项目A发送请求&#xff0c;这里通过jsonp的方式实现跨域访问。 $.ajax({ url:http://10.10.2.256:8280/ssoCheck, //请求的u…

PySide6程序框架设计

pyside6有一个优点自动适配高分辨ui pyqt5需要自己写这部分逻辑 1、主程序代码 DINGSHI01Main.py # -*- coding: utf-8 -*- import sys,time,copy from PySide6.QtWidgets import QWidget,QApplication from PySide6.QtCore import Qt from PySide6 import QtCore, QtGui, Q…

ActiveMQ 反序列化漏洞CVE-2015-5254复现

文章目录 一、产生原因二、利用条件三、利用过程四、PoC&#xff08;概念验证&#xff09;五、poc环境验证使用find搜索vulhub已安装目录打开activeMQ组件查看配置文件端口启动镜像-文件配置好后对于Docker 镜像下载问题及解决办法设置好镜像源地址&#xff0c;进行重启docker查…

数据结构:Win32 API详解

目录 一.Win32 API的介绍 二.控制台程序(Console)与COORD 1..控制台程序(Console): 2.控制台窗口坐标COORD&#xff1a; 3.GetStdHandle函数&#xff1a; &#xff08;1&#xff09;语法&#xff1a; &#xff08;2&#xff09;参数&#xff1a; 4.GetConsoleCursorInf…