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;
}