tcp socket operation easy

前言

以前写tcp的socket操作,都是从头写。
这次维护的cm中要加入新的socket客户端和sokcet服务器的操作,工程中有一部分简单封装的socket函数,封装的不是很好,看着较为难受,而且封装的不全,只有客户端的socket操作。
如果要加入风格不统一的socket封装,写逻辑代码时,必定很难受。主要是弄的心很乱,不能忍。
想重新封装一个好用的tcp的socket操作类,然后将工程旧的socket封装函数都砍掉,换上封装后的socket类。
我给这个工程起名叫tcp_socket_easy, 希望心随所愿:)
封装完后,用起来确实很方便。
基类为socket_base,子类有2个:socket_tcp_client, socket_tcp_server.
不用封到类中的socket函数,放到socket_helper.h。
经过封装后,代码整洁多了。
在工程中自包含了客户端和服务器端的测试代码,用命令行隔开,一个工程就可以当作客户端或服务器。
工程在windows和linux下均有工程文件,都可以编译并运行。
仅进行了类接口的测试,如果要加入现有工程,只需要调整下接口调用的逻辑(e.g. 服务器接受客户端连接后,要开一个线程来处理,服务器继续接受客户端连接)。本工程仅是封装tcp的socket操作,只展现这一个点。

工程下载点

src_tcp_socket_easy.zip

编译测试环境

windows环境: win10x64 + vs2010vc++
linux环境: rh5.4x64 + g++

测试工程的效果

[root@localhost src]# ./tcp_socket_easy -server
--------------------------------------------------------------------------------
tcp_socket_easy 1.0.0.1 2017-12-5 21:31
--------------------------------------------------------------------------------
>> server_proc
client coming :  : 
server.recv_until_over : hello, i'm client
<< server_proc
--------------------------------------------------------------------------------
THE END
--------------------------------------------------------------------------------
[root@localhost src]# ./tcp_socket_easy -client
--------------------------------------------------------------------------------
tcp_socket_easy 1.0.0.1 2017-12-5 21:31
--------------------------------------------------------------------------------
>> client_proc
!client.is_connect_ok()
client.connect("127.0.0.1", 54321, 1) = true
client.recv_until_over : hello, i'm server
<< client_proc
--------------------------------------------------------------------------------
THE END
--------------------------------------------------------------------------------

工程预览

socket_easy实现

// @file socket_base.h

#ifndef __SOCKET_BASE_H__
#define __SOCKET_BASE_H__

#include "socket_helper.h"

NS_SOCKET_EASY_BEGIN

class socket_base {
    public:
        socket_base();
        virtual ~socket_base();

        virtual const char* get_class_name() = 0;

        void set_socket_handle(SOCKET sk) {m_socket = sk;}
        SOCKET& get_socket_handle() {return m_socket;}

        int generate_new_socket(int family, int type, int protocol);
        void close_socket_handle(); // 要在析构中调用,不能为虚
        void close_socket_handle(SOCKET sk);

        void save_last_error();
        int get_last_error() {return m_i_last_error;}
        const char* get_last_error_string() {return strerror(get_last_error());}

        int send_until_over(SOCKET sk, char * buf, int buf_len);
        int recv_until_over(SOCKET sk, char * buf, int buf_len);

    private:        
        int send_one_time(SOCKET sk, char * data, int data_len);
        int recv_one_time(SOCKET sk, char * data, int data_len);

    private:
        SOCKET m_socket;
        int m_i_last_error;
};

NS_SOCKET_EASY_END

#endif // #ifndef __SOCKET_BASE_H__

// @file socket_tcp_client.h

#ifndef __SOCKET_TCP_CLIENT_H__
#define __SOCKET_TCP_CLIENT_H__

#include "socket_base.h"

NS_SOCKET_EASY_BEGIN
class socket_tcp_client : public socket_base {
    public:
        socket_tcp_client();
        virtual ~socket_tcp_client();
        void close_socket_handle();

        virtual const char* get_class_name();

        bool connect(const char * ip, const int port, int time_out_s);
        bool is_connect_ok();

    private:
        bool m_b_socket_connect_ok;
};
NS_SOCKET_EASY_END

#endif // #ifndef __SOCKET_TCP_CLIENT_H__

// @file socket_tcp_server.h

#ifndef __SOCKET_TCP_SERVER_H__
#define __SOCKET_TCP_SERVER_H__

#include "socket_base.h"

NS_SOCKET_EASY_BEGIN
class socket_tcp_server : public socket_base {
    public:
        socket_tcp_server();
        virtual ~socket_tcp_server();
        void close_socket_handle();
        void close_socket_handle(SOCKET sk);

        virtual const char* get_class_name();

        bool listen_local_port(int iport);
        SOCKET accept_client(std::string& str_client_ip, std::string& str_client_port);


    private:
        SOCKET accept_ex(SOCKET fd, struct sockaddr* sa, socklen_t* salenptr);
        bool bind_ex(SOCKET fd, const struct sockaddr* sa, socklen_t salen);
        bool listen_ex(SOCKET fd, int backlog);
};
NS_SOCKET_EASY_END

#endif // #ifndef __SOCKET_TCP_SERVER_H__

// @file socket_helper.h

#ifndef __SOCKET_HELPER_H__
#define __SOCKET_HELPER_H__

#include <sys/types.h>          /* See NOTES */
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>

#ifndef WIN32
// linux
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h> // for bzero
#else
// win
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

#include <windows.h>
#include <ws2tcpip.h> // for socklen_t
#endif // #ifndef WIN32

#ifndef INVALID_SOCKET
#define INVALID_SOCKET          (~0)
#endif

#ifndef SOCKET_ERROR
#define SOCKET_ERROR            (-1)
#endif

#ifndef WIN32
    // linux env
    #ifndef SOCKET
        typedef int SOCKET;
    #endif // #ifndef SOCKET
#endif // #ifndef WIN32

#define NS_SOCKET_EASY ls
#define NS_SOCKET_EASY_BEGIN namespace NS_SOCKET_EASY {
#define NS_SOCKET_EASY_END }

NS_SOCKET_EASY_BEGIN

#ifndef WIN32
// linux
#else
// win
void bzero(void *dst, size_t n);
#endif // #ifndef WIN32

int thread_env_socket_init();
int thread_env_socket_uninit();
bool safe_close_socket(SOCKET& sk);

NS_SOCKET_EASY_END

#endif // #ifndef HELPER

// @file socket_base.cpp

#include "socket_base.h"

NS_SOCKET_EASY_BEGIN

socket_base::socket_base() {
    m_socket = INVALID_SOCKET;
    m_i_last_error = -1;
}

socket_base::~socket_base() {
    close_socket_handle();
}

void socket_base::save_last_error()
{
#ifndef WIN32
        m_i_last_error = errno;
#else
        m_i_last_error = WSAGetLastError();
#endif // #ifndef WIN32
}

int socket_base::generate_new_socket(int family, int type, int protocol)
{
    int i_port_re_use = 1; // enable : socket addr re use
    SOCKET i_sock_sn = INVALID_SOCKET;

    i_sock_sn = socket(family, type, protocol);
    if (i_sock_sn < 0) {
        save_last_error();
    } else {
        // reuse port !
        setsockopt(i_sock_sn, SOL_SOCKET, SO_REUSEADDR, (const char*)&i_port_re_use, sizeof(i_port_re_use));
    }

    return i_sock_sn;
}

int socket_base::send_one_time(SOCKET sk, char * data, int data_len) {
    int i_rc = 0;

    try {
        i_rc = ::send(sk, data, data_len, 0);
        if (SOCKET_ERROR == i_rc) {
            save_last_error();
        }
    } catch (...) {
        i_rc = -1;
    }

    return i_rc;
}

int socket_base::send_until_over(SOCKET sk, char * buf, int buf_len) {
    int i_rc = 0;
    int len = 0;
    while (buf_len > 0) {
        i_rc = send_one_time(sk, buf + len, buf_len);
        if (i_rc < 0) {
            break;
        }

        len += i_rc;
        buf_len -= i_rc;
    }

    return len;
}

int socket_base::recv_one_time(SOCKET sk, char * data, int data_len) {
    int i_rc = 0;

    i_rc = ::recv(sk, data, data_len, 0);
    if (SOCKET_ERROR == i_rc) {
        save_last_error();
    }

    return i_rc;
}

int socket_base::recv_until_over(SOCKET sk, char * buf, int buf_len) {
    int i_rc = 0;
    int len = 0;

    while (buf_len > 0) {
        i_rc = recv_one_time(sk, buf + len, buf_len);
        if (i_rc < 0) {
            break;
        }

        len += i_rc;
        buf_len -= i_rc;
    }

    return len;
}

void socket_base::close_socket_handle()
{
    close_socket_handle(get_socket_handle());
    m_i_last_error = -1;
}

void socket_base::close_socket_handle(SOCKET sk)
{
    safe_close_socket(sk);
}


NS_SOCKET_EASY_END

// @file socket_tcp_client.cpp

#include "socket_tcp_client.h"

NS_SOCKET_EASY_BEGIN

socket_tcp_client::socket_tcp_client()
{
    m_b_socket_connect_ok = false;
}

socket_tcp_client::~socket_tcp_client()
{
    close_socket_handle();
}

const char* socket_tcp_client::get_class_name()
{
    return "socket_tcp_client";
}

void socket_tcp_client::close_socket_handle()
{
    socket_base::close_socket_handle();
    m_b_socket_connect_ok = false;
}

bool socket_tcp_client::connect(const char * ip, const int port, int time_out_s)
{
    bool b_rc = false;
    int i_rc = 0;
    SOCKET sk = INVALID_SOCKET;
    sockaddr_in addr;

    do {
        if ((NULL == ip) || (port < 0)) {
            break;
        }

        if ((SOCKET)INVALID_SOCKET == get_socket_handle()) {
            set_socket_handle(generate_new_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
            if ((SOCKET)INVALID_SOCKET == get_socket_handle()) {
                break;
            }
        }

        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr(ip);
        addr.sin_port = htons(port);

        // convert a text host address to a numeric address
        if (inet_pton(AF_INET, (char *)ip, &addr.sin_addr) <= 0) {
            break;
        }

        // set recv timeout
        timeval tv;
        tv.tv_sec = time_out_s;
        tv.tv_usec = 0;

        setsockopt(get_socket_handle(), SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof tv);

        // connect server port
        m_b_socket_connect_ok = false;
        i_rc = ::connect(get_socket_handle(), (struct sockaddr*) &addr, sizeof(addr));
        if (SOCKET_ERROR == i_rc) {
            save_last_error();
            close_socket_handle();
            break;
        }

        m_b_socket_connect_ok = true;
        b_rc = m_b_socket_connect_ok;
    } while (0);

    return b_rc;
}

bool socket_tcp_client::is_connect_ok()
{
    return (((int)INVALID_SOCKET != get_socket_handle()) && m_b_socket_connect_ok);
}

NS_SOCKET_EASY_END

// @file socket_tcp_server.cpp

#include "socket_tcp_server.h"

NS_SOCKET_EASY_BEGIN

socket_tcp_server::socket_tcp_server()
{
}

socket_tcp_server::~socket_tcp_server()
{
    close_socket_handle();
}

const char* socket_tcp_server::get_class_name()
{
    return "socket_tcp_server";
}

void socket_tcp_server::close_socket_handle()
{
    socket_base::close_socket_handle();
}

void socket_tcp_server::close_socket_handle(SOCKET sk)
{
    socket_base::close_socket_handle(sk);
}

SOCKET socket_tcp_server::accept_ex(SOCKET fd, struct sockaddr* sa, socklen_t* salenptr)
{
    SOCKET sk = INVALID_SOCKET;

    do {
        sk = ::accept(fd, sa, salenptr);
        if (sk < 0) {
            if ((ECONNABORTED == errno) || (EINTR == errno))
                continue;
            else {
                save_last_error();
                break;
            }
        }

        break;
    } while (1);

    return sk;
}

bool socket_tcp_server::bind_ex(SOCKET fd, const struct sockaddr* sa, socklen_t salen)
{
    int i_rc = 0;

    i_rc = ::bind(fd, sa, salen);
    if (i_rc < 0) {
        save_last_error();
    }

    return (0 == i_rc);
}

bool socket_tcp_server::listen_ex(SOCKET fd, int backlog)
{
    int i_rc = 0;

    i_rc = ::listen(fd, backlog);
    if (i_rc < 0) {
        save_last_error();
    }
    return (0 == i_rc);
}

bool socket_tcp_server::listen_local_port(int iport)
{
    bool b_rc = false;
    addrinfo hints;
    addrinfo* res = NULL;
    struct sockaddr_in server_addr;
    SOCKET listenfd = INVALID_SOCKET;
    char sz_buf[0x1000] = {'\0'};
    std::string str_server_port = "";

    memset(&hints, 0, sizeof(struct addrinfo));

    do {
        hints.ai_flags = AI_PASSIVE;
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;

        sprintf(sz_buf, "%d", iport);
        str_server_port = sz_buf;

        if (0 != getaddrinfo(NULL, str_server_port.c_str(), &hints, &res))
        {
            save_last_error();
            break;
        }

        freeaddrinfo(res);

        bzero(&server_addr, sizeof(server_addr));
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(iport);
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

        listenfd = generate_new_socket(AF_INET, SOCK_STREAM, 0);
        if (INVALID_SOCKET == listenfd) {
            break;
        }

        set_socket_handle(listenfd);

        if (!bind_ex(get_socket_handle(), (struct sockaddr*)&server_addr, sizeof(server_addr))) {
            break;
        }

        if (!listen_ex(get_socket_handle(), SOMAXCONN)) {
            break;
        }

        b_rc = true;
    } while (0);

    return b_rc;
}

SOCKET socket_tcp_server::accept_client(std::string& str_client_ip, std::string& str_client_port)
{
    int i_rc = 0;
    SOCKET i_fd = INVALID_SOCKET;
    int clientlen = 0;
    struct sockaddr_in client_addr; 
    sockaddr_storage clientaddr;

    char clienthost[NI_MAXHOST] = {'\0'};
    char clientservice[NI_MAXSERV] = {'\0'};

    clientlen = sizeof(client_addr);
    bzero(&client_addr, sizeof(client_addr));

    str_client_ip = "";
    str_client_port = "";

    do {
        i_fd = accept_ex(get_socket_handle(), (struct sockaddr*)&client_addr, (socklen_t*)&clientlen);
        if (INVALID_SOCKET == i_fd) {
            break;
        }

        i_rc = getnameinfo((sockaddr *)&clientaddr,
            clientlen,
            clienthost,
            sizeof(clienthost), 
            clientservice, 
            sizeof(clientservice), 
            NI_NUMERICHOST|NI_NUMERICSERV);

        if (0 == i_rc) {
            str_client_ip = clienthost;
            str_client_port = clientservice;
        }
    } while (0);

    return i_fd;
}

NS_SOCKET_EASY_END

// @file socket_helper.cpp

#include "socket_helper.h"

NS_SOCKET_EASY_BEGIN

#ifndef WIN32
    // linux
#else
    // win
void bzero(void *dst, size_t n)
{
    memset(dst, 0, n);
}
#endif // #ifndef WIN32

int thread_env_socket_init()
{
#ifndef WIN32
#else
    // win
    int             iRc = 0;
    WSADATA         wsaData;

    iRc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (NO_ERROR != iRc)
    {
        // err
    }
#endif
    return 0;
}

int thread_env_socket_uninit()
{
#ifndef WIN32
#else
    // win
    WSACleanup();
#endif
    return 0;
}

bool safe_close_socket(SOCKET& sk)
{
    bool b_rc = false;

    try {
#ifndef WIN32
        if ((int)INVALID_SOCKET != sk) {
            ::close(sk);
#else
        if ((int)INVALID_SOCKET != sk) {
            closesocket(sk);
#endif
        }
        b_rc = true;
    } catch (...) {
        b_rc = false;
    }

    sk = (int)INVALID_SOCKET;
    return b_rc;
}

NS_SOCKET_EASY_END

接口的测试代码

// @file main.cpp
// @note
// set date on linux env :  date -s "2017-10-29 12:08:00"

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <string.h>

#include "const_define.h"
#include "my_data_type.h"

#include "business_client.h"
#include "business_server.h"

void version();
void help();

int main(int argc, char** argv)
{
    system("clear");
    version();

    NS_SOCKET_EASY::thread_env_socket_init();

    do {
        if (2 != argc) {
            help();
            break;
        }

        if (0 == strcmp(argv[1], CMD_PARAM_RUN_AS_CLIENT)) {
            client_proc();
        } else if (0 == strcmp(argv[1], CMD_PARAM_RUN_AS_SERVER)) {
            server_proc();
        } else {
            help();
        }
    } while (0);

    printf("%s\n", LINE80);
    printf("THE END\n");
    printf("%s\n", LINE80);

    NS_SOCKET_EASY::thread_env_socket_uninit();
    return 0;
}

void version()
{
    printf("%s\n", LINE80);
    printf("%s %s %s\n",
        PROG_NAME,
        PROG_VER,
        PROG_MODIFY_TIME);
    printf("%s\n", LINE80);
}

void help()
{
    printf("%s\n", LINE80);
    printf("usage:\n");
    printf("%s %s\n",
        PROG_NAME,
        CMD_PARAM_RUN_AS_CLIENT);
    printf("%s %s\n",
        PROG_NAME,
        CMD_PARAM_RUN_AS_SERVER);
    printf("%s\n", LINE80);
}

// @file business_server.h

#ifndef __BUSINESS_SERVER_H__
#define __BUSINESS_SERVER_H__

#include "socket_tcp_server.h"

void server_proc();

#endif // #ifndef __BUSINESS_SERVER_H__
// @file business_client.h

#ifndef __BUSINESS_CLIENT_H__
#define __BUSINESS_CLIENT_H__

#include "socket_tcp_client.h"

void client_proc();

#endif // #ifndef __BUSINESS_CLIENT_H__
// @file business_server.cpp

#include <stdlib.h>
#include <stdio.h>

#include "business_server.h"

void server_proc()
{
    int i_tmp = 0;
    SOCKET i_client_fd = INVALID_SOCKET;
    NS_SOCKET_EASY::socket_tcp_server server;
    std::string str_client_ip = "";
    std::string str_client_port = "";
    char sz_buf[0x100] = {'\0'};

    printf(">> server_proc\n");
    do {
        if (!server.listen_local_port(54321)) {
            printf("server.listen_local_port failed : %s\n", server.get_last_error_string());
            break;
        }

        i_client_fd = server.accept_client(str_client_ip, str_client_port);
        if (INVALID_SOCKET == i_client_fd) {
            break;
        }

        printf("client coming : %s : %s\n", str_client_ip.c_str(), str_client_port.c_str());

        // recv
        i_tmp = server.recv_until_over(i_client_fd, sz_buf, (int)sizeof(sz_buf));
        if ((int)sizeof(sz_buf) != i_tmp) {
            printf("server.recv_until_over failed : %s\n", server.get_last_error_string());
            break;
        } else {
            printf("server.recv_until_over : %s\n", sz_buf);
        }

        // send
        strcpy(sz_buf, "hello, i'm server");
        i_tmp = server.send_until_over(i_client_fd, sz_buf, (int)sizeof(sz_buf));
        if ((int)sizeof(sz_buf) != i_tmp) {
            printf("server.send_until_over failed : %s\n", server.get_last_error_string());
            break;
        }

    } while (0);

    server.close_socket_handle(i_client_fd);
    server.close_socket_handle();
    printf("<< server_proc\n");
}

// @file business_client.cpp

#include <stdlib.h>
#include <stdio.h>

#include "business_client.h"

void client_proc()
{
    bool b_rc = false;
    int i_tmp = 0;
    char sz_buf[0x100] = {'\0'};
    NS_SOCKET_EASY::socket_tcp_client client;

    printf(">> client_proc\n");

    do {
        // connect server port
        if (!client.is_connect_ok()) {
            printf("!client.is_connect_ok()\n");
            b_rc = client.connect("127.0.0.1", 54321, 1);
            printf("client.connect(\"127.0.0.1\", 54321, 1) = %s\n", b_rc ? "true" : "false");
            if (!b_rc) {
                printf("client.connect failed : %s\n", client.get_last_error_string());
                break;
            }
        }

        // send
        strcpy(sz_buf, "hello, i'm client");
        i_tmp = client.send_until_over(client.get_socket_handle(), sz_buf, (int)sizeof(sz_buf));
        if ((int)sizeof(sz_buf) != i_tmp) {
            printf("client.send_until_over failed : %s\n", client.get_last_error_string());
            break;
        }

        // recv
        i_tmp = client.recv_until_over(client.get_socket_handle(), sz_buf, (int)sizeof(sz_buf));
        if ((int)sizeof(sz_buf) != i_tmp) {
            printf("client.recv_until_over failed : %s\n", client.get_last_error_string());
            break;
        } else {
            printf("client.recv_until_over : %s\n", sz_buf);
        }
    } while (0);

    // close socket
    client.close_socket_handle();

    printf("<< client_proc\n");
}

// @file const_define.h

#ifndef _CONST_DEFINE_H_
#define _CONST_DEFINE_H_

#define PROG_NAME "tcp_socket_easy"
#define PROG_VER "1.0.0.1"
#define PROG_MODIFY_TIME "2017-12-5 21:31"

#define LINE80 "--------------------------------------------------------------------------------"

// client cmd line : tcp_socket_easy -client
// server cmd line : tcp_socket_easy -server
#define CMD_PARAM_RUN_AS_CLIENT "-client"
#define CMD_PARAM_RUN_AS_SERVER "-server"

#endif // #ifndef _CONST_DEFINE_H_

// @file my_data_type.h

#ifndef _MY_DATA_TYPE_H_
#define _MY_DATA_TYPE_H_

#ifndef NULL
#define NULL 0
#endif // #ifndef NULL

#define MAX_UL ((unsigned long)-1)

#endif // #ifndef _MY_DATA_TYPE_H_

工程配置文件

win版的工程是vs2010vc++的sln.
linux版是自己写的Makefile.

# ==============================================================================
# makefile
#   lostspeed 2017-12-5
# note
#   when first build on vmware's linux, please adjust date time for build project
#   e.g. date -s "2017-12-5 21:49:00"
# ==============================================================================
BIN = tcp_socket_easy
LINE80 = --------------------------------------------------------------------------------
CC = g++ -std=c++98
CFLAGS = -Wall -g
INC = -I. -I./socket_easy
LIBS = -lstdc++ -pthread
LIBPATH = /usr/local/lib

DEPEND_CODE_DIR = ./empty_dir \

DEPEND_CODE_SRC = $(shell find $(DEPEND_CODE_DIR) -name '*.cpp')
DEPEND_CODE_OBJ = $(DEPEND_CODE_SRC:.cpp=.o)

# root code dir is ./'s code, e.g. main.cpp
ROOT_CODE_SRC = $(shell find ./ -name '*.cpp')
ROOT_CODE_OBJ = $(ROOT_CODE_SRC:.cpp=.o)

# if no sub code dir, must fill a sub dir exist but empty. e.g. ./empty_dir
# if have sub code dir, fill it like DEPEND_CODE_DIR
# e.g. ./xx_subdir/xx_type/
SUB_CODE_DIR = ./socket_easy
SUB_CODE_SRC = $(shell find $(SUB_CODE_DIR) -name '*.cpp')
SUB_CODE_OBJ = $(SUB_CODE_SRC:.cpp=.o)

help:
    clear

    @echo $(LINE80)
    @echo "ROOT_CODE_SRC = " $(ROOT_CODE_SRC)
    @echo "ROOT_CODE_OBJ = " $(ROOT_CODE_OBJ)

    @echo "DEPEND_CODE_DIR = " $(DEPEND_CODE_DIR)
    @echo "DEPEND_CODE_SRC = " $(DEPEND_CODE_SRC)
    @echo "DEPEND_CODE_OBJ = " $(DEPEND_CODE_OBJ)

    @echo "SUB_CODE_DIR = " $(SUB_CODE_DIR)
    @echo "SUB_CODE_SRC = " $(SUB_CODE_SRC)
    @echo "SUB_CODE_OBJ = " $(SUB_CODE_OBJ)

    @echo "INC = " $(INC)

clean:
    clear
    @echo $(LINE80)
    @echo make clean
    rm -f $(BIN) $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)

all:$(BIN)
    @echo $(LINE80)
    @echo make all
    chmod 777 $(BIN)
    find . -name $(BIN)

$(BIN) : $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
    $(CC) $(CFLAGS) -o $@ $^

.cpp.o:
    $(CC) -c $(CFLAGS) $^ -o $@ $(INC) -L$(LIBPATH) $(LIBS)

rebuild:
    make clean
    @echo $(LINE80)
    make all

rebuild_and_run:
    make rebuild
    @echo $(LINE80)
    ./$(BIN)

总结

如果有好用的封装,我是不可能封装的, 太懒了。
只有不能忍或必须要动手的情况,才会自己封装。
但是封装也挺占用时间的,这个封装类+测试代码,整了2次,用了9小时(7+2).
以后,如果是tcp的socket操作,我就用自己的封装类,看着用着都舒服 :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值