用c++实现在一个进程里同时实现server和client
时间: 2023-10-01 10:03:11 浏览: 107
C++项目-C++实现云盘项目实战-包括client端和server端
在C++中,可以使用套接字(socket)来实现进程之间的通信。一个进程既可以作为服务器(server),也可以作为客户端(client),并且在同一进程中同时运行。
以下是一个简单的示例,展示了如何在同一进程中实现服务器和客户端:
```c++
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
std::mutex mtx;
void server()
{
// 创建套接字
SOCKET serverSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSock == INVALID_SOCKET)
{
std::cerr << "创建套接字失败!" << std::endl;
return;
}
// 绑定套接字
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(serverSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cerr << "绑定套接字失败!" << std::endl;
closesocket(serverSock);
return;
}
// 监听套接字
if (listen(serverSock, SOMAXCONN) == SOCKET_ERROR)
{
std::cerr << "监听套接字失败!" << std::endl;
closesocket(serverSock);
return;
}
// 等待客户端连接
std::cout << "等待客户端连接..." << std::endl;
sockaddr_in clientAddr;
int clientAddrLen = sizeof(clientAddr);
SOCKET clientSock = accept(serverSock, (sockaddr*)&clientAddr, &clientAddrLen);
if (clientSock == INVALID_SOCKET)
{
std::cerr << "接受连接失败!" << std::endl;
closesocket(serverSock);
return;
}
// 接收客户端消息
char recvBuf[1024] = { 0 };
while (true)
{
int ret = recv(clientSock, recvBuf, sizeof(recvBuf), 0);
if (ret <= 0)
{
std::cerr << "客户端已断开连接!" << std::endl;
break;
}
// 处理客户端消息
std::string msg = recvBuf;
mtx.lock();
std::cout << "客户端说:" << msg << std::endl;
mtx.unlock();
}
// 关闭套接字
closesocket(clientSock);
closesocket(serverSock);
}
void client()
{
// 创建套接字
SOCKET clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSock == INVALID_SOCKET)
{
std::cerr << "创建套接字失败!" << std::endl;
return;
}
// 连接服务器
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(12345);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(clientSock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
std::cerr << "连接服务器失败!" << std::endl;
closesocket(clientSock);
return;
}
// 发送消息给服务器
std::string msg;
while (true)
{
std::getline(std::cin, msg);
if (msg.empty())
{
break;
}
int ret = send(clientSock, msg.c_str(), msg.length(), 0);
if (ret <= 0)
{
std::cerr << "发送消息失败!" << std::endl;
break;
}
}
// 关闭套接字
closesocket(clientSock);
}
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cerr << "初始化套接字库失败!" << std::endl;
return -1;
}
// 在不同的线程中分别运行服务器和客户端
std::thread serverThread(server);
std::thread clientThread(client);
serverThread.join();
clientThread.join();
WSACleanup();
return 0;
}
```
在这个示例中,主函数中启动了两个线程,一个运行服务器,一个运行客户端。服务器和客户端都使用相同的套接字库,但是服务器使用 `socket()` 创建套接字,绑定地址和端口,监听连接请求,接受客户端连接,接收客户端消息,处理客户端消息,并且关闭套接字。客户端使用 `socket()` 创建套接字,连接服务器,发送消息给服务器,并且关闭套接字。在服务器中,使用互斥锁保护共享的输出流,避免输出混乱。
阅读全文