能用C++写一个基于TCP协议的简易聊天机械人代码吗?能同时允许多个客户端同时连接的且分为客户端和服务器,能用vs2022写吗
时间: 2024-03-27 19:38:20 浏览: 52
基于TCP协议的聊天工具,包括客户端跟服务器
5星 · 资源好评率100%
当然可以!以下是一个简单的基于TCP协议的聊天机器人代码示例,可以在VS2022中编写。
服务器端代码:
```cpp
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
int main()
{
// 初始化Winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOK = WSAStartup(ver, &wsData);
if (wsOK != 0)
{
std::cerr << "Can't initialize winsock! Quitting" << std::endl;
return 0;
}
// 创建一个socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
std::cerr << "Can't create a socket! Quitting" << std::endl;
return 0;
}
// 绑定IP地址和端口到socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
// 告诉Winsock这个socket是用来监听的
listen(listening, SOMAXCONN);
// 等待一个客户端连接
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; // 客户端的远程名称
char service[NI_MAXHOST]; // 服务名称(即端口号)
ZeroMemory(host, NI_MAXHOST); // 确保这些缓冲区为空
ZeroMemory(service, NI_MAXHOST);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
std::cout << host << " connected on port " << service << std::endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::cout << host << " connected on port " <<
ntohs(client.sin_port) << std::endl;
}
// 关闭监听socket
closesocket(listening);
// 循环接收和发送数据
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
// 等待客户端发送数据
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
std::cerr << "Error in recv(). Quitting" << std::endl;
break;
}
if (bytesReceived == 0)
{
std::cout << "Client disconnected" << std::endl;
break;
}
// 输出客户端发送的内容
std::cout << "Received: " << std::string(buf, 0, bytesReceived) << std::endl;
// 回复客户端
send(clientSocket, buf, bytesReceived + 1, 0);
}
// 关闭socket
closesocket(clientSocket);
// 清理Winsock
WSACleanup();
return 0;
}
```
客户端代码:
```cpp
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
int main()
{
// 初始化Winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOK = WSAStartup(ver, &wsData);
if (wsOK != 0)
{
std::cerr << "Can't initialize winsock! Quitting" << std::endl;
return 0;
}
// 创建socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
std::cerr << "Can't create a socket! Quitting" << std::endl;
return 0;
}
// 连接到服务器
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
inet_pton(AF_INET, "127.0.0.1", &hint.sin_addr);
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
std::cerr << "Can't connect to server! Quitting" << std::endl;
closesocket(sock);
WSACleanup();
return 0;
}
// 循环发送和接收数据
char buf[4096];
std::string userInput;
do
{
// 提示用户输入内容
std::cout << "> ";
std::getline(std::cin, userInput);
if (userInput.size() > 0)
{
// 发送内容到服务器
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
// 等待服务器回复
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
// 输出服务器回复内容
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
}
}
} while (userInput.size() > 0);
// 关闭socket
closesocket(sock);
// 清理Winsock
WSACleanup();
return 0;
}
```
这个聊天机器人可以同时允许多个客户端连接。你可以通过在服务器端循环调用accept()函数来处理多个客户端连接。
阅读全文