从 Python 接收C++字符串

Receiving strings in C++ from Python

本文关键字:字符串 C++ 接收 Python      更新时间:2023-10-16

我正在尝试通过套接字将布尔值从客户端(Python(发送到服务器(C++(。

所以我使用了 json 并将布尔值转换为字符串格式并通过套接字发送字符串。

这是我的代码: 客户端(Python(:

# TCP Client Code
host="128.0.0.1"            # Set the server address to variable host
port=8080               # Sets the variable port to 4446
from socket import *             # Imports socket module
import json
s=socket(AF_INET, SOCK_STREAM)      # Creates a socket

s.connect((host,port))          # Connect to server address
print "Successfully connected to the server and ready to send some data"
data= json.dumps("{"A":true,"B":false,"C":false,"D":false}")
s.send(data)

msg=s.recv(1024)            # Receives data upto 1024 bytes and stores in variables msg
print "Message from server : " + msg
s.close()                            # Closes the socket
# End of code

现在我以字符串格式接收它们以及 \t 标签。 如何解释发送的布尔值并将其分配给C++中的必需变量。

这是我在服务器端的代码(C++(:

using namespace std;
//Server side
int main(int argc, char *argv[8080])
{
bool Style1;
//buffer to send and receive messages with
char msg[1500];
//setup a socket and connection tools
sockaddr_in servAddr;
memset((char*)&servAddr, 0,sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(8080);
//open stream oriented socket with internet address
//also keep track of the socket descriptor
int serverSd = socket(AF_INET, SOCK_STREAM, 0);
if(serverSd < 0)
{
cerr << "Error establishing the server socket" << endl;
exit(0);
}

//bind the socket to its local address
int bindStatus = bind(serverSd, (struct sockaddr*) &servAddr, 
sizeof(servAddr));
if(bindStatus < 0)
{
cerr << "Error binding socket to local address" << endl;
exit(0);
}
cout << "Waiting for a client to connect..." << endl;

//listen for up to 5 requests at a time
listen(serverSd, 5);

//receive a request from client using accept
//we need a new address to connect with the client
sockaddr_in newSockAddr;
socklen_t newSockAddrSize = sizeof(newSockAddr);

//accept, create a new socket descriptor to 
//handle the new connection with client
int newSd = accept(serverSd, (sockaddr *)&newSockAddr, &newSockAddrSize);
if(newSd < 0)
{
cerr << "Error accepting request from client!" << endl;
exit(1);
}
cout << "Connected with client!" << endl;

//receive a message from the client (listen)
cout << "Awaiting client response..." << endl;
memset(&msg, 0, sizeof(msg));//clear the buffer
recv(newSd, (char*)&msg, sizeof(msg), 0);
if(!strcmp(msg, "exit"))
{
cout << "Client has quit the session" << endl;
}
string str(msg);
cout << "Client: " << msg << endl;
cout << ">";
string data = "Instructions Received n";
memset(&msg, 0, sizeof(msg)); //clear the buffer
strcpy(msg, data.c_str());
if(data == "exit")
{
//send to the client that server has closed the connection
send(newSd, (char*)&msg, strlen(msg), 0);
}
//send the message to client
send(newSd, (char*)&msg, strlen(msg), 0);
//we need to close the socket descriptors after we're all done

close(newSd);
close(serverSd);
cout << "Connection closed..." << endl;
return 0;   
}

我是初学者,感谢你们帮助我。

仅供参考 - 如果我在收到后以 C++ 打印字符串,它看起来像这样

"{\"A\":true,\"B\":false,\"C\":false,\">

D\":false}">

感谢大家的建议,我尝试在C++中使用 json 并进行了一些更改

#include<iostream>
#include <jsoncpp/json/json.h>
using namespace std;
void decode()
{
bool a,b,c,d;
string text = "{"A":true,"B":false,"C":false,"D":false}";
Json::Value root;
Json::Reader reader;
bool parsingSuccessful = reader.parse( text, root );
if ( !parsingSuccessful )
{
cout << "Error parsing the string" << endl;
}

const Json::Value mynamesA = root["A"];
const Json::Value mynamesB = root["B"];
const Json::Value mynamesC = root["C"];
const Json::Value mynamesD= root["D"];

cout<<mynamesA<<endl;
cout<<mynamesB<<endl;
cout<<mynamesC<<endl;
cout<<mynamesD<<endl;

}
int main()
{   
decode();
return 0;
}

现在它的印刷

true
false
false
false

不出所料。 但我想将这些值分配给bool a,b,c,d;我该怎么做??

最好控制实际发送的内容。

这一行:

data= json.dumps("{"A":true,"B":false,"C":false,"D":false}")

高度可疑:当它应该用于对象以生成 JSON 字符串时,您对已经是 JSON 编码的字符串使用json.dumps

我已经在交互式Python中对其进行了测试,并得到了:

>>> data= json.dumps("{"A":true,"B":false,"C":false,"D":false}")
>>> print(data)
"{"A":true,"B":false,"C":false,"D":false}"
>>> print([(i, hex(ord(i))) for i in data])   # control individual characters
[('"', '0x22'), ('{', '0x7b'), ('', '0x5c'), ('"', '0x22'), ('A', '0x41'), ('', '0x5c'), ('"', '0x22'), (':', '0x3a'), ('t', '0x74'), ('r', '0x72'), ('u', '0x75'), ('e', '0x65'), (',', '0x2c'), ('', '0x5c'), ('"', '0x22'), ('B', '0x42'), ('', '0x5c'), ('"', '0x22'), (':', '0x3a'), ('f', '0x66'), ('a', '0x61'), ('l', '0x6c'), ('s', '0x73'), ('e', '0x65'), (',', '0x2c'), ('', '0x5c'), ('"', '0x22'), ('C', '0x43'), ('', '0x5c'), ('"', '0x22'), (':', '0x3a'), ('f', '0x66'), ('a', '0x61'), ('l', '0x6c'), ('s', '0x73'), ('e', '0x65'), (',', '0x2c'), ('', '0x5c'), ('"', '0x22'), ('D', '0x44'), ('', '0x5c'), ('"', '0x22'), (':', '0x3a'), ('f', '0x66'), ('a', '0x61'), ('l', '0x6c'), ('s', '0x73'), ('e', '0x65'), ('}', '0x7d'), ('"', '0x22')]

这是有问题的双引号("(和反斜杠((是由Python代码发送的证据。

你想要的可能是:

data = '{"A":true,"B":false,"C":false,"D":false}'  # directly store the json string

# build the json string from a dict
data = json.dumps({'A': True, 'B': False, 'C': False, 'D': False})

如果可能,最好使用 JSON 解析库。这是您可以使用的RapidJSON教程的链接。

如果您想自己编写解决方案,请尝试以下操作。

自编码解决方案

遍历字符串,找到"""的所有索引并将它们存储在向量中。如果键值对中没有一个值是字符串,则可以使用它来查找键。 因此,如果你有一个包含 3 和 7 的向量,那么你的键从 4 开始,到 6 结束。

可以使用类似的逻辑来提取值。遍历字符串并找到第一个出现的":"。在此之后,查找第一个出现的",",该位置位于最后一个找到的 ": " 的索引之后。 因此,如果您有 9 和 15,那么您的值将从 11 开始,以 14 结束。

请注意,当您到达最后一个值时,它将按照您的示例以"]"结尾。因此,如果未找到逗号,请查找"]"或可能的" "。

bool findKeyIndices(string s, vector<int> & kIndices) {
string substr = """;
vector<int> indices;
size_t index = s.find(substr, 0);
while (index != string::npos) {
indices.push_back(index);
s.find(substr, index+1);
}
if (indices.size() % 2 != 0)
return FALSE;
for(int x =0; x < indices.size(); x++) {
if(indices.at(x) % 2 == 0) {
kIndex.push_back(++x);
} else {
kIndex.push_back(--x)
}
}
return TRUE;
} 
bool findValIndices(string s, vector<int> & vIndices){
string start = ": ", endOne = ",", endTwo = "]";
vector<int> indices;
size_t index = s.find(start, 0), backupIndex;
while (index != string::npos) {
indices.push_back(index);
backupIndex = index;
s.find(endOne, index+1);
if(index != string::npos) {
indices.push_back(index);
} else {
s.find(endTwo, backupIndex + 1);
if(backupIndex != string::npos){
index = backupIndex;
} else {
return FALSE;
}
}
}
if (indices.size() % 2 != 0)
return FALSE;
for(int x =0; x < indices.size(); x++) {
if(indices.at(x) % 2 == 0) {
vIndex.push_back(x + 2);
} else {
vIndex.push_back(--x)
}
}
}

如果您可以假设值仅为真或假,则解决方案可能会更简单。在这种情况下,您可以找到每个键的起始索引以及所有"true"和"false"子字符串的起始索引。然后你可以从那里找出哪个键与真或假相关联。

例如,如果键的起始索引为 [2, 10],而"true"的起始索引为 4,则从 2 开始的键将与 true 相关联,因为键 1-start

增强藻类

上述算法假设键值对中没有一个值是字符串。您可以修改上面的代码,这样您就不必做出该假设。

以下是步骤:

  1. 查找所有出现的 "\" 并将索引存储在向量中 (称之为报价指数(
  2. 查找所有出现的逗号并存储 向量中的索引
  3. 查找可以是 用于查找最后一个值的结尾。在您的示例中 评论,是"]"。

使用以下公式确定键值对:

quote-open-indx

现在,x 可以是值或字符串。 使用如下所示的过程来确定 x 是什么并相应地进行解析。

  1. 报价指数中的第一个和第二个索引将始终包含一个键。因此,您可以假设第一个引号结束索引位于 quoteIndices.at(1(。假设它等于 5。
  2. 如果报价指数中有另一个值,使得它更大 大于 5 但小于第一个逗号索引,则您的值为 字符串。否则,它不是。