http客户端简单demo

socket.h头文件

#pragma once
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
using std::string;

namespace MySocket
{
  class Socket
  {
  public:
    Socket();
    Socket(int sockfd);
    ~Socket();

    bool bind(const string &ip, int port);
    bool listen(int backlog);
    bool connet(const string &ip, int port);
    int accept();
    int send(const char *buf, int len);
    int recv(char *buf, int len);
    void close();

    bool set_non_blocking();
    bool set_send_buffer(int size);
    bool set_recv_buffer(int size);
    bool set_linger(bool active, int seconds);
    bool set_keepalive();
    bool set_reuse_addr();

  protected:
    string ip_;
    int port_;
    int sockfd_;
  };
}

socket.cpp

#include "socket.h"
#include <fcntl.h>
//#include <socket/socket.h>
using namespace MySocket;

Socket::Socket() : ip_(""), port_(0), sockfd_(0)
{
  sockfd_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sockfd_ < 0) 
  {
    printf("socket bind error: errno=%d, errmsg=%s\n", errno, strerror(errno));
  }
  printf("create socket success!\n");
}

Socket::Socket(int sockfd) : ip_(""), port_(0), sockfd_(sockfd)
{

}

Socket::~Socket()
{
  close();
}

bool Socket::bind(const string &ip, int port)
{
  struct sockaddr_in sockaddr;
  std::memset(&sockaddr, 0, sizeof(sockaddr));
  sockaddr.sin_family = AF_INET;
  sockaddr.sin_addr.s_addr = inet_addr(ip.c_str());
  sockaddr.sin_port = htons(port);
  if (::bind(sockfd_, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
  {
      printf("socket bind error: errno=%d, errmsg=%s\n", errno, strerror(errno));
      return false;
  }

  ip_ = ip;
  port_ = port;
  printf("socket bind success: ip=%s port=%d\n", ip.c_str(), port);
  return true;
}

bool Socket::listen(int backlog)
{
  if (::listen(sockfd_, backlog) < 0)
  {
      printf("socket listen error: errno=%d errmsg=%s\n", errno, strerror(errno));
      return false;
  }
  
  printf("socket listen ...\n");
  return true;
}

bool Socket::connet(const string &ip, int port)
{
  struct sockaddr_in sockaddr;
  std::memset(&sockaddr, 0, sizeof(sockaddr));
  sockaddr.sin_family = AF_INET;
  sockaddr.sin_addr.s_addr = inet_addr(ip.c_str());
  sockaddr.sin_port = htons(port);
  if (::connect(sockfd_, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
  {
      printf("socket connect error: errno=%d errmsg=%s\n", errno, strerror(errno));
      return false;
  }
  ip_ = ip;
  port_ = port;
  printf("socket connet success: ip=%s port = %d\n", ip.c_str(), port);
  return true;
}

int Socket::accept()
{
  int connfd = ::accept(sockfd_, nullptr, nullptr);
  if (connfd < 0)
  {
      printf("socket accept error: errno=%d errmsg=%s\n", errno, strerror(errno));
      return false;
  }
  printf("socket accept success: connfd=%d \n", connfd);
  return connfd;
}

int Socket::send(const char *buf, int len)
{
  return ::send(sockfd_, buf, len, 0);
}

int Socket::recv(char *buf, int len)
{
  return ::recv(sockfd_, buf, len, 0);
}

void Socket::close()
{
  if (sockfd_ > 0)
  {
    ::close(sockfd_);
  }
}

bool Socket::set_non_blocking()
{
  int flags = ::fcntl(sockfd_, F_GETFL, 0);
  if (flags < 0)
  {
    printf("socket set_non_blocking error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }

  flags |= O_NONBLOCK;
  if (::fcntl(sockfd_, F_SETFL, flags) < 0)
  {
    printf("socket set_non_blocking error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  return true;
}

bool Socket::set_send_buffer(int size)
{
  int buff_size = size;
  if (::setsockopt(sockfd_, SOL_SOCKET, SO_SNDBUF, &buff_size, sizeof(buff_size)) < 0)
  {
    printf("socket set_send_buffer error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  return true;
}

bool Socket::set_recv_buffer(int size)
{
  int buff_size = size;
  if (::setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &buff_size, sizeof(buff_size)) < 0)
  {
    printf("socket set_receive_buffer error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  return true;
}
bool Socket::set_linger(bool active, int seconds)
{
  struct linger tmp;
  std::memset(&tmp, 0, sizeof(tmp));
  tmp.l_onoff = active;
  tmp.l_linger = seconds;
  if (::setsockopt(sockfd_, SOL_SOCKET, SO_LINGER, &tmp, sizeof(tmp)) < 0)
  {
    printf("socket set_linger error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  return true;
}

bool Socket::set_keepalive()
{
  int keepalive = 1; // enable keepalive
  int keepcnt = 6;  // count
  int keepintvl = 1; // interval
  if (setsockopt(sockfd_, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0)
  {
    printf("socket set_keepalive error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  // if (setsockopt(sockfd_, SOL_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt)) < 0)
  // {
  //   printf("socket set_keepalive error:error=%d, errmsg = %s", errno, strerror(errno));
  //   return false;
  // }

  // if (setsockopt(sockfd_, SOL_TCP, TCP_KEEPINTVL, &keepintvl    , sizeof(keepintvl)) < 0)
  // {
  //   printf("socket set_keepalive error:error=%d, errmsg = %s", errno, strerror(errno));
  //   return false;
  // }
  return true;
}

bool Socket::set_reuse_addr()
{
  int optval = 1;
  if (setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
  {
    printf("socket set_reuse_addr error:error=%d, errmsg = %s", errno, strerror(errno));
    return false;
  }
  return true;
}

server_socket.h

#pragma once
#include "socket.h"

namespace MySocket
{
  class ServerSocket : public Socket
  {
  public:
    ServerSocket() = delete;
    ServerSocket(const string& ip, int port);
    ~ServerSocket() = default;
  };  
} // namespace name

server_socket.cpp

#include "server_socket.h"
using namespace MySocket;

ServerSocket::ServerSocket(const string& ip, int port) : Socket()
{
  //set_non_blocking();
  set_recv_buffer(10*1024);
  set_send_buffer(10*1024);
  set_linger(true, 0);
  set_keepalive();
  set_reuse_addr();
  bind(ip, port);
  listen(1024);
  ip_ = ip;
  port_ = port;
}

client_socket.h

#pragma once
#include "socket.h"

namespace MySocket  
{
  class ClientSocket : public Socket
  {
  public:
    ClientSocket() = delete;
    ClientSocket(const string& ip, int port);
    ~ClientSocket()= default;
  };
}

client_socket.cpp

#include "client_socket.h"
using namespace MySocket;

ClientSocket::ClientSocket(const string& ip, int port) : Socket()
{
  connet(ip, port);
  ip_ = ip;
  port_ = port;
}

server.cpp

#include <iostream>
#include "socket/server_socket.h"

using namespace MySocket;
int main()
{
    // // 1. 创建 socket
    // Socket server;

    // // 2. 绑定 socket
    // string ip = "127.0.0.1";
    // int port = 8080;
    // server.bind(ip, port);

    // // 3. 监听 socket
    // server.listen(1024);
    ServerSocket server( "127.0.0.1", 8080);

    while (true)
    {
        // 4. 接收客户端连接
        int connfd = server.accept();
        if (connfd < 0)
        {
          break;
        }
        Socket client(connfd);

        char buf[1024] = {0};

        // 5. 接收客户端的数据
        size_t len = client.recv(buf, sizeof(buf));
        printf("recv: conn=%d msg=%s\n", connfd, buf);

        // 6. 向客服端发送数据
        client.send(buf, len);
    }

    // // 7. 关闭 socket
    // server.close();
  return 0;
}

client.cpp

// #include <iostream>

// #include <cstring>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <arpa/inet.h>
// #include <unistd.h>
// #include <string>
// using std::string;
#include "socket/client_socket.h"
using namespace MySocket;

int main()
{
    // // 1. 创建 socket
    // Socket client;

    // // 2. 连接服务端
    // string ip = "127.0.0.1";
    // int port = 8080;
    // client.connet(ip, port);
    ClientSocket client("127.0.0.1", 8080);

    // 3. 向服务端发送数据
    string data = "hello world";
    client.send(data.c_str(), data.size());

    // 4. 接收服务端的数据
    char buf[1024] = {0};
    client.recv(buf, sizeof(buf));

    printf("recv: %s\n", buf);

    // // 5. 关闭 socket
    // client.close();

    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5.0)

project(hello)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)

set(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -O2 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -std=c++11 -O2 -Wall -g -ggdb")

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/socket)

#link_directories(
#  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth
#)
#file(GLOB_RECURSE SORRCES "socket/*cpp")
set(SORRCES ${CMAKE_CURRENT_SOURCE_DIR}/socket/socket.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/socket/server_socket.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/socket/client_socket.cpp)

add_executable(server ${SORRCES} server.cpp)
add_executable(client ${SORRCES} client.cpp)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值