Linux网络编程 socket通信技术 函数封装

目录

一:面向对象设计思想

二:网络事件

三:socket通信 类的设计


一:面向对象设计思想

在前面的几篇文章介绍了服务器搭建socket通信的实现,只是在程序主入口main函数中做了简单测试,但在正常业务中,为了使得业务流程更加清晰明了,就需要采用封装思想,面向对象设计封装主要功能函数;

在本节文章中,主要目标就是把socket通信连接改写面向对象程序设计,需要思考搭建哪几个类以及每个类需要实现什么样的功能(用一个类的封装设计来搭建一整个模块的功能),具体的封装实现是要看数据传输的方式和业务的大致结构,因此封装不是固定的,适合的才是最好的;

常见服务器搭建类的设计包括有:地址类 IO类 socket基类 TCP服务器类 TCP客户端类 UDP类

二:网络事件

TCP 网络编程最本质的是处理三个半事件

1.连接的建立,包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接

2.连接的断开,包括主动断开 (close 或 shutdown) 和被动断开 (read 返回 0)

3.消息到达,文件描述符可读

   这是最为重要的一个事件,对它的处理方式决定了网络编程的风格(阻塞还是非阻塞,如何处理分包,应用层的缓冲如何设计等等)

4.消息发送完毕,这算半个

   对于低流量的服务,可以不必关心这个事件;另外,这里“发送完毕”是指将数据写入操作系统的缓冲区,将由 TCP 协议栈负责数据的发送与重传,不代表对方已经收到数据

三:socket通信 类的设计

地址类的设计

#pragma once
#include <sys/types.h>         
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
class CHostAddress
{
public:
	CHostAddress(unsigned short port);
	~CHostAddress();
	unsigned short getPort();
	void setPort(unsigned short port);
	struct sockaddr_in getAddr_in();
	struct sockaddr* getAddr();
	int getLength();
private:
	unsigned short port;
	struct sockaddr_in s_addr;
	int length;

};
#include "CHostAddress.h"

CHostAddress::CHostAddress(unsigned short port)
{
    this->port = port;
    this->s_addr.sin_family = AF_INET;//IPV4版本选择
    this->s_addr.sin_addr.s_addr = INADDR_ANY;
    this->s_addr.sin_port = this->port;
    this->length = sizeof(this->s_addr);
}

CHostAddress::~CHostAddress()
{
}

unsigned short CHostAddress::getPort()
{
    return this->port;
}

void CHostAddress::setPort(unsigned short port)
{
    this->port = port;
}

sockaddr_in CHostAddress::getAddr_in()
{
    return  this->s_addr;
}

sockaddr* CHostAddress::getAddr()
{
    return (struct sockaddr*)&(this->s_addr);
}

int CHostAddress::getLength()
{
    return this->length;
}

socket通信 基类 

#pragma once
#include <sys/types.h>         
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
class CBaseSocket
{
public:
	CBaseSocket(unsigned short port);
	virtual ~CBaseSocket();
	int getSocketfd();
	void start();//运行网络连接
	virtual void stop() = 0;
	virtual void run() = 0;
protected:
	int socketfd;
};
#include "CBaseSocket.h"

CBaseSocket::CBaseSocket(unsigned short port)
{
    this->socketfd = 0;
}

CBaseSocket::~CBaseSocket()
{
}

int CBaseSocket::getSocketfd()
{
    return this->socketfd;
}

void CBaseSocket::start()
{
    this->socketfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (this->socketfd < 0)
    {
        perror("socket error");
    }
    else
    {
        this->run();
    }
    
}

TCP服务器类的设计

#pragma once
#include "CBaseSocket.h"
#include"CHostAddress.h"
#include <sys/types.h>         
#include <sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h>
#include<iostream>
#define LISTEN_MAX_NUM 10

using namespace std;
class CTcpServer :
    public CBaseSocket
{
public:
    CTcpServer(unsigned short port);
    ~CTcpServer();
    void run();
    void stop();
    CHostAddress* getAddress();
    void setAddress(CHostAddress* address);
private:
    CHostAddress* address;
};
#include "CTcpServer.h"

CTcpServer::CTcpServer(unsigned short port):CBaseSocket(port)
{
    this->address = new CHostAddress(port);
}

CTcpServer::~CTcpServer()
{
    delete this->address;
}

void CTcpServer::run()
{
    int opt_val = 1;
    if (setsockopt(this->socketfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt_val, sizeof(opt_val))==-1)
    {
        perror("setsockopt error");
    }
    if (bind(this->socketfd, this->address->getAddr(), this->address->getLength()) == -1)
    {
        perror("bind error");
    }
    if (listen(this->socketfd, LISTEN_MAX_NUM) == -1)
    {
        perror("listen error");
    }
    cout << "服务器启动成功" << endl;
}

void CTcpServer::stop()
{
    if (this->socketfd != 0)
    {
        close(this->socketfd);
        this->socketfd = 0;
    }
}

CHostAddress* CTcpServer::getAddress()
{
    return this->address;
}

void CTcpServer::setAddress(CHostAddress* address)
{
    this->address = address;
}

main.cpp 程序主入口测试

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

using namespace std;

int main()
{
	CTcpServer* tcp = new CTcpServer(10000);
	tcp->start();
	
	return 0;
}

可以做个简单测试,测试下服务器是否能够成功启动

服务器搭建,类的封装设计还待完善,在后面文章中会继续补充

【Linux网络编程】- Socket封装

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenruhan_QAQ_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值