實現一個TCPSocket類
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define CHECK_RET(q) if(q==false){return -1}
class TCPSocket
{
public:
TCPSocket():_sockfd(-1)
{}
~TCPSocket()
{}
bool Socket()
{
_sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(_sockfd<0)
{
perror("socket error");
return false;
}
return true;
}
bool Bind(std::string &ip,uint16_t port)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
addr.sin_addr.s_addr=inet_addr(ip.c_str());
socklen_t len=sizeof(struct sockaddr_in);
int ret=bind(_sockfd,(struct sockaddr*)&addr,len);
if(ret<0)
{
perror("bind error");
return false;
}
return true;
}
bool Listen(int backlog=5)
{
int ret=listen(_sockfd,backlog);
if(ret<0)
{
perror("listen error");
return false;
}
return true;
}
bool Accept(TCPSocket &client,std::string &client_ip,uint16_t &client_port)
{
struct sockaddr_in addr;
socklen_t len=sizeof(struct sockaddr_in);
int sockfd=accept(_sockfd,(struct sockaddr*)&addr,&len);
if(sockfd<0)
{
perror("accept error");
return false;
}
client.SetFd(sockfd);
client_ip=inet_ntoa(addr.sin_addr);
client_port=ntohs(addr.sin_port);
return true;
}
void SetFd(int sockfd)
{
_sockfd=sockfd;
}
bool Connect(std::string &server_ip,uint16_t server_port)
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(server_port);
addr.sin_addr.s_addr=inet_addr(server_ip.c_str());
socklen_t len=sizeof(struct sockaddr_in);
int ret=connect(_sockfd,(struct sockaddr*)&addr,len);
if(ret<0)
{
perror("connect error");
return false;
}
return true;
}
bool Recv(std::string &buf)
{
char tmp[4096];
int ret=recv(_sockfd,tmp,4096,0);
if(ret<0)
{
perror("recv error");
return false;
}
else if(ret==0)
{
printf("peer shutdown\n");
return false;
}
buf.assign(tmp,ret);
return true;
}
bool Send(std::string &buf)
{
int ret=send(_sockfd,buf.c_str(),buf.size(),0);
if(ret<0)
{
perror("send error");
return false;
}
return true;
}
bool Close()
{
close(_sockfd);
return true;
}
private:
int _sockfd;
};
int main()
{
return 0;
}
TCP服務端程序
#include "tcpsocket.hpp"
int main(int argc,char* argv[])
{
if(argc!=3)
{
std::cout<<"./tcp_server 192.168.32.130 9000\n";
return -1;
}
std::string ip=argv[1];
uint16_t port=atoi(argv[2]);
TCPSocket sock;
CHECK_RET(sock.Socket());
CHECK_RET(sock.Bind(ip,port));
CHECK_RET(sock.Listen());
while(1)
{
TCPSocket clientsock;
std::string client_ip;
uint16_t client_port;
if(sock.Accept(clientsock,client_ip,client_port)==false)
{
continue;
}
std::cout<<"new client:"<<client_ip<<":"<<client_port<<std::endl;
std::string buf;
clientsock.Recv(buf);
std::cout<<"client say:"<<buf<<std::endl;
buf.clear();
std::cout<<"server say:";
fflush(stdout);
std::cin>>buf;
clientsock.Send(buf);
}
sock.Close();
return 0;
}
TCP客戶端程序
#include "tcpsocket.hpp"
#include <signal.h>
void sigcb(int signo)
{
printf("connection closed\n");
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
std::cout<<"./tcp_client 192.168.32.130 9000\n";
return -1;
}
std::string ip=argv[1];
uint16_t port=atoi(argv[2]);
signal(SIGPIPE,sigcb);
TCPSocket sock;
CHECK_RET(sock.Socket());
CHECK_RET(sock.Connect(ip,port));
while(1)
{
std::string buf;
std::cout<<"client say:";
fflush(stdout);
std::cin>>buf;
sock.Send(buf);
buf.clear();
sock.Recv(buf);
std::cout<<"server say:"<<buf<<std::endl;
}
sock.Close();
return 0;
}