strtok() 更改我的缓冲区,我需要存储一些在任意时间更改的数据,我该怎么做?
Posted
技术标签:
【中文标题】strtok() 更改我的缓冲区,我需要存储一些在任意时间更改的数据,我该怎么做?【英文标题】:strtok() change my buffer, I need stored some data that change in an arbitrary time, how can I do this? 【发布时间】:2021-08-20 04:46:56 【问题描述】:我有一个坐标列表,其中包含从 Python 服务器发送到 C++ 客户端(如缓冲区)的坐标,然后我需要拆分每个坐标,为此我使用了 strtok(),但是当第一次对函数进行标记时,请执行此操作正确地,当我的 while 循环重复并收到一个新的坐标列表时,该函数返回先前拆分的第一个标记,我需要保存新的坐标列表并将其拆分为标记,就像第一次一样,任何人都知道我的问题是什么或更好不使用 strtok() 的解决方法?
这是我的 C++ 客户端代码
#define _CTR_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
#include <iostream>
#include <sstream>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <typeinfo>
using namespace std;
int main()
char delimitador[] = ",";
WORD wVersionRequested;
WSADATA wsaData;
int err, N;
char* length;
string D, Coordenada;
wVersionRequested = MAKEWORD(1, 1);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
return -1;
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1)
WSACleanup();
return -1;
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(2070);
connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
const char* baseCh = "hello" ;
char recvBuf[50], expected[50];
send(sockClient, baseCh, strlen(baseCh), 0);
while (1 == 1)
recv(sockClient, recvBuf, strlen(recvBuf), 0);
strcpy(expected, recvBuf);
char *token = strtok(expected, delimitador);
if (token != NULL);
while (token != NULL)
printf("Token %s\n", token);
token = strtok(NULL, delimitador);
send(sockClient, baseCh, strlen(baseCh), 0);
closesocket(sockClient);
WSACleanup();
getchar();
return 0;
这是我的 Python 服务器代码
import socket
import time
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 2070))
server.listen(0)
connection, address = server.accept()
Hand = []
while True:
recv_str=connection.recv(1024)[0:5]
print("enter 1")
recv_str=recv_str.decode("ascii")
if not recv_str:
break
print( recv_str)
while True:
time.sleep(0.5)
Hand.append(1)
Hand.append(20)
Hand.append(25)
connection.send( bytes("%s," %Hand, encoding="ascii"))
recv_str=connection.recv(1024)[0:5]
print(Hand)
print(recv_str)
Hand = []
connection.close()
input("enter end")
if __name__ == '__main__':
main()
enter image description here
我已经放了我使用的正确代码,主要问题是我需要在未定义的时间连续接收来自 Python 服务器的消息,这个消息是一组坐标,你如何看到函数 strtok () 更改我的缓冲区,我只需要拆分数据而不更改原始缓冲区变量,就像我的第一个标记化结果一样,但每次我的缓冲区更改时。
【问题讨论】:
strtok
函数记录了这是预期的行为。请参阅Notes 部分。相反,编写您自己的标记器,而不是依赖于旧的 C 函数,例如 strtok
。 *** 上有很多链接展示了如何创建这样的分词器。
请注意,不能保证recv
会收到在一个send
中发送的所有内容。 TCP/IP 是一个非结构化的八位字节流。
你不能假设socket()
成功了。你不能假设connect()
成功了。你不能假设recv()
成功了。您不能假设 recv()
没有为流结束返回 -1。你不能假设recv()
填满了缓冲区。您不能假设 recv()
收到了整个以空字符结尾的字符串。你不能假设send()
成功了。将strlen()
传递给recv()
是没有意义的。这里的基本错误太多了。
【参考方案1】:
我的问题不是我的 strtok() 函数,在阅读了我的一篇古老的问题后,我意识到我的问题出在 recv() 函数中,我的更正是
recv(sockClient, recvBuf, strlen(recvBuf), 0);
为
recv(sockClient, recvBuf, sizeof(recvBuf), 0);
这解决了我的问题,最后,我可以从 Python 服务器接收到 C++ 客户端的连续数据。
【讨论】:
以上是关于strtok() 更改我的缓冲区,我需要存储一些在任意时间更改的数据,我该怎么做?的主要内容,如果未能解决你的问题,请参考以下文章