头文件(tcpsocket.hpp)
#include <string>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define CHECK_RET(q) if((q) == false){return -1;}
class TcpSocket{
public:
TcpSocket() : _sockfd(-1){}
void SetSockFd(int fd){
_sockfd = fd;
}
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 = 10) {
int ret = listen(_sockfd, backlog);
if (ret < 0) {
perror("listen error");
return false;
}
return true;
}
bool Connect(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 = connect(_sockfd, (struct sockaddr*)&addr, len);
if (ret < 0) {
perror("connect error");
return false;
}
return true;
}
bool Accept(TcpSocket &sock, struct sockaddr_in *addr = NULL){
struct sockaddr_in _addr;
socklen_t len = sizeof(struct sockaddr_in);
int newfd = accept(_sockfd, (struct sockaddr*)&_addr, &len);
if (newfd < 0) {
perror("accept error");
return false;
}
if (addr != NULL) {
memcpy(addr, &_addr, len);
}
sock.SetSockFd(newfd);
return true;
}
bool Recv(std::string &buf) {
char tmp[4096] = {0};
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);
_sockfd = -1;
}
private:
int _sockfd;
};
客户端(tcp_client.cpp)
#include <iostream>
#include "tcpsocket.hpp"
int main(int argc, char *argv[]){
if (argc != 3 ) {
std::cout<<"./tcp_cli ip port\n";
return -1;
}
std::string ip = argv[1];
uint16_t port = atoi(argv[2]);
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;
}
服务器(tcp_server.cpp)
#include <iostream>
#include "tcpsocket.hpp"
int main(int argc, char *argv[]){
if (argc != 3) {
printf("./tcp_srv ip port\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 clisock;
struct sockaddr_in cliaddr;
if (sock.Accept(clisock, &cliaddr) == false) {
continue;
}
printf("new connect client:%s:%d\n",
inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
std::string buf;
clisock.Recv(buf);
printf("client say:%s\n", buf.c_str());
buf.clear();
std::cout<<"server say:";
fflush(stdout);
std::cin>>buf;
clisock.Send(buf);
}
sock.Close();
return 0;
}