实现一个简单的TCP网络程序(客户端输入字符大小写互转)

GitHub地址—>:—点我—

封装 TCP socket

tcp_socket.hpp

#pragma once
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>

using namespace std;

class TcpSocket{
  public:
    TcpSocket()
      :_fd(-1)
    {
      _fd=socket(AF_INET,SOCK_STREAM,0);
      if(_fd<0)
        perror("socket");
    }
    bool Close(){
      if(_fd!=-1)
        close(_fd);
      return true;
    }
    bool Bind(const string& ip,const int port){
      sockaddr_in addr;
      addr.sin_family=AF_INET;
      addr.sin_addr.s_addr=inet_addr(ip.c_str());
      addr.sin_port=htons(port);
      int n=bind(_fd,(sockaddr*)&addr,sizeof(addr));
      if(n<0){
        perror("bind");
        return false;
      }
      return true;
    }
    //声明sockfd处于监听状态,设置等待队列大小
    bool Listen(const int log=5){
      int n=listen(_fd,log);
      if(n<0){
        perror("listen");
        return false;
      }
      return true;
    }
    //从等待队列上取一个,链接该客户端,如果没有则阻塞
    int Accept(TcpSocket* NewSock,string& ip,int& port){
      sockaddr_in addr;
      socklen_t len=sizeof(addr);
      int newSock=accept(_fd,(sockaddr*)&addr,&len);
      if(newSock<0){
        perror("accept");
        return -1;
      }
      ip=inet_ntoa(addr.sin_addr);
      port=ntohs(addr.sin_port);
      NewSock->_fd=newSock;

      return 1;
    }
    //客户端调用该函数链接服务器
    bool Connect(const string& ip,const int port){
      sockaddr_in addr;
      addr.sin_family=AF_INET;
      addr.sin_addr.s_addr=inet_addr(ip.c_str());
      addr.sin_port=htons(port);
      int n=connect(_fd,(sockaddr*)&addr,sizeof(addr));
      if(n<0){
        perror("connect");
        return false;
      }
      return true;
    }
    //接收请求
    int Recv(string& msg)
    {
      char buf[1024*2]={0};
      int n=recv(_fd,buf,sizeof(buf)-1,0);
      if(n<0){
        perror("recv");
        return -1;
      }
      else if(n==0){
        return 0;
      }
      msg=buf;
      return 1;
    }
    //写回请求
    bool Send(const string& msg)
    {
      int n=send(_fd,msg.c_str(),msg.size(),0);
      if(n<0){
        perror("send");
        return false;
      }
      return true;
    }
  private:
    int _fd;
};

TCP通用服务器

tcp_server.hpp

#pragma once
#include"tcp_socket.hpp"


//服务器一启动就要绑定ip和port

typedef void (*Handler)(const string& buf,string& ret);

class TcpServer{
  public:
    TcpServer(const string& ip,const int port)
      :_ip(ip)
       ,_port(port)
    {}
    ~TcpServer(){
      _sock.Close();
    }
    bool Start(Handler hand){
      if(_sock.Bind(_ip,_port)==false)
        return false;
      if(_sock.Listen()==false)
        return false;
      cout<<"server start ok~"<<endl;
      while(1){
        TcpSocket newSock;
        //从等待队列里链接一个客户端
        //此处传_ip和_port并不好,最好重新定义变量
        int n=_sock.Accept(&newSock,_ip,_port);
        if(n<0){
          continue;
        }
        printf("客户端[%s:%d]已连接\n",_ip.c_str(),_port);
        while(1){
          //读取请求
          string msg;
          n=newSock.Recv(msg);
          if(n<0){
            printf("recv error\n");
            continue;
          }
          else if(n==0){
            printf("客户端已断开!\n");
            newSock.Close();
            break;
          }
          cout<<"用户输入了:"<<msg<<endl;
          //处理请求
          string ret;
          hand(msg,ret);
          printf("[%s:%d]msg:%s ret:%s\n",_ip.c_str(),_port,msg.c_str(),ret.c_str());
          //写回请求
          n=newSock.Send(ret);
          if(n<0){
            continue;
          }
        }
      } 
    }
  private:
    TcpSocket _sock;
    string _ip;
    int _port;
};

TCP通用客户端

tcp_client.hpp

#pragma once
#include"tcp_socket.hpp"

//客户端
class TcpClient{
  public:
    TcpClient(const string& ip,const int port)
      :_server_ip(ip)
       ,_server_port(port)
  {
    if(_sock.Connect(_server_ip,_server_port)==false)
      perror("Connect");
  }
    ~TcpClient(){
      _sock.Close();
    }
    bool Send(const string& msg){
      return _sock.Send(msg);
    }
    bool Recv(string& ret){
      return _sock.Recv(ret);
    }
  private:
    TcpSocket _sock;
    string _server_ip;
    int _server_port;
};

字符转换服务器

dict_server.cc

#include"tcp_server.hpp"

void test(const string& msg,string& ret){
  auto it=msg.begin();
  while(it!=msg.end()){
    if(*it>='a'&&*it<='z'){
      ret.push_back(*it-32);
    }
    else{
      ret.push_back(*it+32);
    }
    ++it;
  }
}
int main(int argc,char* argv[]){
  if(argc<2)
  {
    perror("main");
    return 1;
  }
  TcpServer server(argv[1],9090);
  server.Start(test);
  return 0;
}

字符转换客户端

dict_client.cc

#include"tcp_client.hpp"

int main(int argc,char *argv[]){
  if(argc<2){
    perror("main");
    return 1;
  }
  TcpClient client(argv[1],9090);
  //发送请求
  string buf;
  cout<<"请输入内容"<<endl;
  while(cin>>buf)
  {
    client.Send(buf);
    string ret;
    client.Recv(ret);
    cout<<"ret:"<<ret<<endl;
    cout<<"请输入内容"<<endl;
  }

  return 0;
}
发布了161 篇原创文章 · 获赞 52 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_42837885/article/details/103147955