千家信息网

C++socket网络编程(跨平台)实战HTTP服务器(三)

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,封装TCP类封装一下tcp类, 步骤还可以简化,直接放上代码类名:XTCPxtcp.h#ifndef _XTCP_H_#define _XTCP_H_#include #include class X
千家信息网最后更新 2025年12月02日C++socket网络编程(跨平台)实战HTTP服务器(三)

封装TCP类


封装一下tcp类, 步骤还可以简化,

直接放上代码类名:XTCP


xtcp.h

#ifndef _XTCP_H_#define _XTCP_H_#include #include class XTCP{public:XTCP();virtual ~XTCP();public:int CreateSocket();//创建socket 反悔socketbool Bind(unsigned short port);//绑定端口XTCP Accept();//反回一个对象void Close();//关闭 主动做int Recv(char *buf, int bufsize);//接收int Send(const char *buf, int sendsize);//发送int m_sock = 0;unsigned short m_port = 0;std::string ip;};#endif //_XTCP_H_

xtcp.cpp

#include "XTCP.h"#ifdef WIN32#include #define socklen_t int#else#include #include #include #include #define closesocket close#include #endifXTCP::XTCP(){#ifdef WIN32static bool first = true; //保证只进入一次if (first){first = false;WSADATA ws;WSAStartup(MAKEWORD(2, 2), &ws);}#endif}XTCP::~XTCP(){}int XTCP::CreateSocket(){m_sock = socket(AF_INET, SOCK_STREAM, 0);if (m_sock == -1){printf("create socket failed!\n");}return m_sock;}bool  XTCP::Bind(unsigned short port){sockaddr_in sa;sa.sin_family = AF_INET;sa.sin_port = htons(port);sa.sin_addr.s_addr = htonl(0);if (bind(m_sock, (sockaddr*)&sa, sizeof(sa))){printf("bind port err\n");//绑定成功return false;}//侦听listen(m_sock, 10);//绑定失败return true;}void XTCP::Close(){if (m_sock <= 0) return;closesocket(m_sock);}XTCP XTCP::Accept(){XTCP tcp;sockaddr_in sadd;socklen_t len = sizeof(sadd);printf("lsiteb ... accept ok\n");//这里会阻塞 只有等待有新的连接 才会执行下面的代码int client = accept(m_sock, (sockaddr*)&sadd, &len);//反悔判断m_sock是否为0就行了if (client <= 0)return tcp; printf("client connect ok\n");//输出端口号和信息tcp.ip = inet_ntoa(sadd.sin_addr);//网络字节序转本地字节序哦tcp.m_port = ntohs(sadd.sin_port);//记录sockettcp.m_sock = client;printf("IP: %s:port: %d\n", tcp.ip.c_str(), tcp.m_port);return tcp;}int XTCP::Recv(char *buf, int bufsize){return recv(m_sock, buf, bufsize, 0);}int XTCP::Send(const char *buf, int sendsize){//buf 必须发送制定大小   保证发送全部成功int s = 0;  //以发送的  发送大小减去以及发送的while (s != sendsize){//反回就是发送的长度int len = send(m_sock, buf + s, sendsize - s, 0);if (len <= 0)break;s += len;  //加上发送的长度}return s;}

测试代码

#include "XTCP.h"#include class TcpThread{public://线程入口函数 创建一个void Main(){char buf[1024];for (;;){memset(buf, 0, sizeof(buf));int recv_len = client.Recv( buf, sizeof(buf) - 1);if (recv_len <= 0)break;if (strstr(buf, "quit") != NULL){char re[] = "quit success\n";int sendlen = client.Send(re, strlen(re) + 1);break;}char *p_ok = "ok\n";int sendlen = client.Send(p_ok,strlen(p_ok));printf("recv %s\n", buf);}client.Close();delete this;}//用户的socketXTCP client;};int main(int argc,char*argv[]){unsigned short port = 8016;XTCP mytcp;//创建mytcp.CreateSocket();//绑定if (!mytcp.Bind(port))return -1;for (;;){XTCP client = mytcp.Accept();//创建线程TcpThread *th = new TcpThread();th->client = client;std::thread sthr(&TcpThread::Main, th);// 释放主线程占用的资源sthr.detach();}mytcp.Close();getchar();return 0;}

原理就是: 创建一个对象XTCP server,有一个int变量,是用来记录创建的socket.的,他用来和用户建立连接,然后服务器必须要绑定端口,Bind里自动侦听。(调用了listen函数)

然后就是反回一个用户client的XTCP对象,把这个对象赋值给上面

的线程类里的成员,应为他TcpThread*th = new TcpThread();

他里面有一个th->client = client; 把他赋值给这个client.

然后创建线程在线程里等待数据收发, 这个new的对象 是在

线程函数里进行释放的 也就是closesocket后面有一个delete this. ,最后就是th->detach() 是释放主线程占用的子线程

的资源,。



移植到linux

先看下makefile

SRC 添加main.cpp 和 XTCP.cpp 就行了

CC=g++SRC=main.cpp XTCP.cppOBJ=hello.oEXEC=mancstart:        $(CC) $(SRC) -o $(EXEC) -std=c++11 -lpthread$(OBJ):        $(CC)  $(OBJ) -c $(SRC)clean:        rm -f $(OBJ) $(EXEC)run:        ./$(EXEC)

执行make start 编译连接

执行make run 执行


成功并发,多个客户端



封装TCP类到Windowsd的dll动态库

将一个类封装到dll和linux的so

在这个博客里讲:

http://12158490.blog.51cto.com/12148490/1947885













0