用c++中写出客户端和服务端代码利用udp协议引入txt文档进行机器人一问一答,而不是直接把文档的所有内容打印出来。
时间: 2024-01-22 15:19:39 浏览: 23
以下是一个简单的客户端和服务端代码,用于利用UDP协议进行机器人一问一答,并从txt文档中读取问题和答案。该程序的工作流程如下:
1. 服务端首先读取txt文档中的数据,并将问题和答案存储在map中。
2. 客户端向服务端发送一个问题。
3. 服务端接收到问题后,从map中查找对应的答案,并将答案发送回客户端。
4. 客户端接收到答案后打印出来,然后再次向服务端发送另一个问题,重复以上步骤。
服务端代码:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
// 初始化Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
cout << "WSAStartup failed: " << iResult << endl;
return 1;
}
// 创建socket
SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serverSocket == INVALID_SOCKET) {
cout << "socket failed: " << WSAGetLastError() << endl;
WSACleanup();
return 1;
}
// 绑定socket到本地地址和端口
sockaddr_in localAddr;
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(8888);
localAddr.sin_addr.s_addr = INADDR_ANY;
iResult = bind(serverSocket, (sockaddr*)&localAddr, sizeof(localAddr));
if (iResult == SOCKET_ERROR) {
cout << "bind failed: " << WSAGetLastError() << endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 从txt文档中读取问题和答案,并存储在map中
ifstream infile("qa.txt");
map<string, string> qaMap;
string line;
while (getline(infile, line)) {
string question = line.substr(0, line.find(","));
string answer = line.substr(line.find(",") + 1);
qaMap[question] = answer;
}
infile.close();
// 循环接收和处理客户端请求
while (true) {
char recvBuf[1024];
sockaddr_in clientAddr;
int clientAddrLen = sizeof(clientAddr);
// 接收客户端请求
iResult = recvfrom(serverSocket, recvBuf, sizeof(recvBuf), 0, (sockaddr*)&clientAddr, &clientAddrLen);
if (iResult == SOCKET_ERROR) {
cout << "recvfrom failed: " << WSAGetLastError() << endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 查找答案并发送回客户端
string question(recvBuf, iResult);
map<string, string>::iterator it = qaMap.find(question);
string answer = "Sorry, I don't know.";
if (it != qaMap.end()) {
answer = it->second;
}
iResult = sendto(serverSocket, answer.c_str(), answer.length(), 0, (sockaddr*)&clientAddr, clientAddrLen);
if (iResult == SOCKET_ERROR) {
cout << "sendto failed: " << WSAGetLastError() << endl;
closesocket(serverSocket);
WSACleanup();
return 1;
}
}
// 关闭socket和清理Winsock
closesocket(serverSocket);
WSACleanup();
return 0;
}
```
客户端代码:
```c++
#include <iostream>
#include <string>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main()
{
// 初始化Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
cout << "WSAStartup failed: " << iResult << endl;
return 1;
}
// 创建socket
SOCKET clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (clientSocket == INVALID_SOCKET) {
cout << "socket failed: " << WSAGetLastError() << endl;
WSACleanup();
return 1;
}
// 设置服务器地址和端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 循环发送和接收消息
while (true) {
// 发送问题
string question;
cout << "Please enter your question: ";
getline(cin, question);
iResult = sendto(clientSocket, question.c_str(), question.length(), 0, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
cout << "sendto failed: " << WSAGetLastError() << endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
// 接收答案
char recvBuf[1024];
int serverAddrLen = sizeof(serverAddr);
iResult = recvfrom(clientSocket, recvBuf, sizeof(recvBuf), 0, (sockaddr*)&serverAddr, &serverAddrLen);
if (iResult == SOCKET_ERROR) {
cout << "recvfrom failed: " << WSAGetLastError() << endl;
closesocket(clientSocket);
WSACleanup();
return 1;
}
// 打印答案
string answer(recvBuf, iResult);
cout << "Answer: " << answer << endl;
}
// 关闭socket和清理Winsock
closesocket(clientSocket);
WSACleanup();
return 0;
}
```
注意:在运行该程序之前,需要在同一目录下创建一个名为“qa.txt”的txt文档,并将问题和答案以逗号分隔的形式写入该文档中。例如:
```
What is your name?,My name is Robot.
What is the time now?,It is 2:30 PM.
```
另外,该程序仅为示例代码,可能存在一些潜在的问题和安全隐患,实际使用时需要进行更加完善的测试和优化。