如何使用winsock2库将程序发送到C中的当前工作目录?

2024-03-28 09:22:34 发布

您现在位置:Python中文网/ 问答频道 /正文

这是我的密码:

#include <stdio.h>
#include <unistd.h>
#include <windows.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main(){
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serverAddr, clientAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(6969);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    listen(serverSocket, 1);

    int s_size = sizeof(struct sockaddr_in);
    SOCKET clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &s_size);

    char cwd[1024];
    getcwd(cwd, 1024);

    printf(cwd);

    send(clientSocket, cwd, sizeof(cwd), 0);

    return 0;
}

它的目的是将程序的cwd发送到python脚本,但是每当我运行python脚本时,当它接收到cwd时,就会出现以下错误:

cwd = clientSocket.recv(1024).decode("utf-8").strip()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd4 in position 44: invalid continuation byte

每当我在C程序上打印cwd时,它都会毫无问题地打印出来。 我尝试过如下方式终止字符串:

cwd[strlen(cwd)] = 0;

它没有改变任何事情

我最好的猜测是,实际路径和空终止符之间的数据是导致python脚本端编码错误的原因,但是我无法为路径分配足够的内存,因为在分配内存之前我无法知道路径的长度,所以我选择了1024,因为我觉得这是一个合理的值

有人知道我怎么解决这个问题吗

编辑: 我解决了。由于缓冲区大(1024),cwd字符串和实际字符串中有很多垃圾。我设法为cwd分配内存,并将其重新分配到strlen()

char *cwd = malloc(1024*sizeof(char));
getcwd(cwd, 1024);
realloc(cwd, strlen(cwd));

printf(cwd);

send(clientSocket, cwd, strlen(cwd), 0);

这对我有用


Tags: 字符串in路径脚本includesinstructchar
1条回答
网友
1楼 · 发布于 2024-03-28 09:22:34

我不懂Python,但相信我看到了这里发生的事情:这似乎是两种不同的处理字符串的方法之间的阻抗不匹配。这需要几个步骤

在C端,它是一个字符缓冲区:

char cwd[1024];
getcwd(cwd, sizeof cwd);
send(clientSocket, cwd, sizeof(cwd), 0);

当前目录字符串之后的cwd缓冲区的内容将是一个NUL字节加上堆栈中的随机垃圾,整个缓冲区将通过网络发送到Python程序

我最初的建议是只发送有效的数据:

send(clientSocket, cwd, strlen(cwd), 0);  // don't do this after all

它不发送垃圾,但现在我们发现另一个问题:接收端需要1024字节:

cwd = clientSocket.recv(1024).decode("utf-8").strip()

问题是,发送方传输的字节要少得多(长度为/home/steve/myproject或其他什么),而且由于TCP套接字不遵守消息边界,因此它仍在尝试读取完整的1024字节

我怀疑连接重置是因为您的C程序在发送之后退出,这会关闭套接字,Python端在接收完所有内容之前观察到这个关闭

解决这个问题的正确方法可能涉及接收端的超时和缓冲,但是这看起来需要做很多工作,所以我会稍微改变一下方向

现在我们将返回到发送一个固定大小的缓冲区(如您所建议的1024),这意味着双方都同意数据大小,但是您必须修改Python端,以便只提取字符串中感兴趣的部分,而忽略NUL字节及其以外的内容

在Python方面,您仍然需要执行cwd = clientSocket.read(1024),但是接下来必须执行缓冲区操作以找出第一个NUL字节的位置,并且只能在缓冲区中使用最多(但不包括)该字符

得到的子集(比如47字节)将是一个您应该能够解码和使用的字符串

根据Python如何操作缓冲区并将它们转换为字符串,结果可能会有所不同;我不知道

相关问题 更多 >