TCP_server.h
#ifndef __TCP_H_
#define __TCP_H_
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
using namespace std;
//服务端类
class server
{
private:
int port; // 服务器监听的端口号
int server_fd; // 服务器套接字文件描述符
int client_fd; // 客户端套接字文件描述符
public:
//有参构造
server(int port):port(port),server_fd(-1),client_fd(-1)
{}
~server(){
closeServer();
}
// 启动服务器,创建套接字并绑定和监听
bool start();
// 接收客户端连接
bool acceptClient();
// 接收客户端发送的数据
string receiveData();
// 向客户端发送数据
void sendData(const string &data);
// 关闭服务器和客户端连接
void closeServer();
};
class client
{
private:
string server_ip; // 服务器的 IP 地址
int port; // 服务器的端口号
int sock_fd; // 客户端套接字文件描述符
public:
client(const string &server_ip, int port) : server_ip(server_ip), port(port), sock_fd(-1) {}
~client(){
}
// 连接到服务器
bool connectToServer();
// 发送数据到服务器
void sendData(const string &data);
// 从服务器接收数据
string receiveData();
// 关闭客户端连接
void closeConnection() {
if (sock_fd >= 0) {
close(sock_fd); // 关闭客户端连接
sock_fd = -1;
}
}
};
#endif
TCP服务端.cpp
#include "TCP_server.h"
// 启动服务器,创建套接字并绑定和监听
bool server::start()
{
// 创建套接字
server_fd = socket(AF_INET, SOCK_STREAM, 0); // 将创建的套接字存储到成员变量 server_fd 中
if (-1 == server_fd)
{
std::cout << "创建套接字失败" << std::endl;
return false;
}
// 填写信息结构体
// 使用的是 IPv4 网络信息结构体,不用使用通用信息结构体
struct sockaddr_in server_addr;
// 清空结构体
memset(&server_addr, 0, sizeof(server_addr));
// 确定协议 选择 IPV4
server_addr.sin_family = AF_INET;
// 端口号
server_addr.sin_port = htons(port); // 端口号随便定
// IP 地址
server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
// 绑定
if (0 > bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
{
cout << server_fd << std::endl;
cout << "绑定失败" << std::endl;
close(server_fd);
return false;
}
// 监听
if (-1 == listen(server_fd, 1))
{
std::cout << "监听失败" << std::endl;
close(server_fd);
return false;
}
cout << "启动成功" << std::endl;
return true;
}
// 接收客户端连接
bool server::acceptClient()
{
sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
// 接收客户端连接请求,阻塞等待直到有连接到达
client_fd = accept(server_fd, (sockaddr*)&client_addr, &client_len); // 使用类成员变量 server_fd
if (client_fd < 0) {
cout << "获取失败" << endl;
return false;
}
std::cout << "连接成功" << std::endl;
return true;
}
// 接收客户端发送的数据
string server::receiveData()
{
if(client_fd < 0)
{
cout << "没有客户端连接" << endl;
return " ";
}
char buf[1024];
memset(buf,0,sizeof(buf));
size_t buf_rev_size=recv(client_fd,buf,sizeof(buf),0);
if(buf_rev_size < 0)
{
cout << "接收失败" << endl;
return " ";
}
cout << "buf" <<endl;
return string(buf,buf_rev_size);
}
// 向客户端发送数据
void server::sendData(const string &data)
{
if(client_fd < 0)
{
cout << "没有客户端连接" << endl;
return ;
}
send(client_fd,data.c_str(),data.size(),0);
}
void server::closeServer() {
if (client_fd >= 0) {
close(client_fd); // 关闭客户端连接
client_fd = -1;
}
if (server_fd >= 0) {
close(server_fd); // 关闭服务器套接字
server_fd = -1;
}
}
main_server.cpp
#include "TCP_server.h"
int main(int argc, char const *argv[])
{
server server(3242); // 创建一个监听端口的服务器
// 启动服务器
if (!server.start())
{
return -1;
}
while (1)
{
// 等待客户端连接
if (!server.acceptClient())
{
return -1;
}
// 接收客户端发送的信息
string message = server.receiveData();
cout << "Received: " << message << endl;
// 向客户端发送一条消息
server.sendData(message);
}
// 关闭服务器
server.closeServer();
return 0;
}
TCP_client.h
#ifndef __TCP_H_
#define __TCP_H_
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
using namespace std;
class client
{
private:
string server_ip; // 服务器的 IP 地址
int port; // 服务器的端口号
int sock_fd; // 客户端套接字文件描述符
public:
client(const string &server_ip, int port) : server_ip(server_ip), port(port), sock_fd(-1) {}
~client(){
}
// 连接到服务器
bool connectToServer();
// 发送数据到服务器
void sendData(const string &data);
// 从服务器接收数据
string receiveData();
// 关闭客户端连接
void closeConnection();
};
#endif
TCP服务端.cpp
#include "TCP_server.h"
// 启动服务器,创建套接字并绑定和监听
bool server::start()
{
// 创建套接字
server_fd = socket(AF_INET, SOCK_STREAM, 0); // 将创建的套接字存储到成员变量 server_fd 中
if (-1 == server_fd)
{
std::cout << "创建套接字失败" << std::endl;
return false;
}
// 填写信息结构体
// 使用的是 IPv4 网络信息结构体,不用使用通用信息结构体
struct sockaddr_in server_addr;
// 清空结构体
memset(&server_addr, 0, sizeof(server_addr));
// 确定协议 选择 IPV4
server_addr.sin_family = AF_INET;
// 端口号
server_addr.sin_port = htons(port); // 端口号随便定
// IP 地址
server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
// 绑定
if (0 > bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)))
{
cout << server_fd << std::endl;
cout << "绑定失败" << std::endl;
close(server_fd);
return false;
}
// 监听
if (-1 == listen(server_fd, 1))
{
std::cout << "监听失败" << std::endl;
close(server_fd);
return false;
}
cout << "启动成功" << std::endl;
return true;
}
// 接收客户端连接
bool server::acceptClient()
{
sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
// 接收客户端连接请求,阻塞等待直到有连接到达
client_fd = accept(server_fd, (sockaddr*)&client_addr, &client_len); // 使用类成员变量 server_fd
if (client_fd < 0) {
cout << "获取失败" << endl;
return false;
}
std::cout << "连接成功" << std::endl;
return true;
}
// 接收客户端发送的数据
string server::receiveData()
{
if(client_fd < 0)
{
cout << "没有客户端连接" << endl;
return " ";
}
char buf[1024];
memset(buf,0,sizeof(buf));
size_t buf_rev_size=recv(client_fd,buf,sizeof(buf),0);
if(buf_rev_size < 0)
{
cout << "接收失败" << endl;
return " ";
}
cout << "buf" <<endl;
return string(buf,buf_rev_size);
}
// 向客户端发送数据
void server::sendData(const string &data)
{
if(client_fd < 0)
{
cout << "没有客户端连接" << endl;
return ;
}
send(client_fd,data.c_str(),data.size(),0);
}
void server::closeServer() {
if (client_fd >= 0) {
close(client_fd); // 关闭客户端连接
client_fd = -1;
}
if (server_fd >= 0) {
close(server_fd); // 关闭服务器套接字
server_fd = -1;
}
}
main_client.cpp
#include "TCP_client.h"
int main(int argc, char const *argv[])
{
client client("127.0.0.1", 3242); // 创建一个连接到 127.0.0.1:8080 的客户端
while(1)
{
if (!client.connectToServer()) {
return -1;
}
// 向服务器发送一条消息
string buf;
cout << "请输入" << endl;
cin >> buf;
client.sendData(buf);
if(buf == "结束")
{
// 关闭客户端连接
client.closeConnection();
return 0;
}
// 接收服务器的回应
string message = client.receiveData();
cout << "Received: " << message << std::endl;
}
return 0;
}