如何将消息从 python 服务器正确发送到 C++ 客户端?

How to send messages properly from python server to c++ client?

我有一个 python 服务器 运行,代码如下:

import socket
ss=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ss.bind(('0.0.0.0',8080))
ss.listen(5)
cs,adr=ss.accept()
print("Got a connection from:"+str(adr))
while 1:
    msg=input('Enter your message:')
    cs.send(msg.encode('ascii'))
cs.close()

对于客户端,我使用的是 C++。
client.h:

#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable:4996)
class client {
private:
    const char* IP;
    int PORT;
    SOCKET sock;
public:
    client(char* ip, int port){
        IP = ip;
        PORT = port;
    }
    void createSession();//Creates socket and connects with the server.
    void sendData(char* message);//Sends message to the server, it works fine
    char* receive()
    {
        char message[2000];
        if (recv(sock, message, 2000, 0) == SOCKET_ERROR)
        {
            WSACleanup();
            return (char*)"Failed to receive Message";
        }
        return message;
    }
};

client.cpp:

#include"client.h"
#include<iostream>
#define IP "127.0.0.1"
#define port 8080
using namespace std;
int main()
{
    client c1((char*)IP, port);
    c1.createSession();
    while (1)
    {
        char* message;
        message = c1.receive();
        cout << IP << ':' << port << " Says: " << message << endl;
    }
    return 0;
}

但我收到的消息是垃圾邮件。我猜这是一个转换错误,因为对于 python 客户端,我会在接收时先使用 recv(length).decode('ascii') 解码消息。我该如何解决这个问题?

char* receive()
{
    char message[2000];
    if (recv(sock, message, 2000, 0) == SOCKET_ERROR)
    {
        WSACleanup();
        return (char*)"Failed to receive Message";
    }
    return message;
}
...
message = c1.receive();
cout << IP << ':' << port << " Says: " << message << endl;

多处错误:

  • 您正在将数据读入函数堆栈 (message[2000]) 上分配的缓冲区。该缓冲区将在函数退出后自动释放,因此您从函数中 return 不再存在。
  • 打印时,您将消息视为 [=12=] 终止的 char[],即使它没有 [=12=] 终止。这意味着收到消息后的垃圾将被打印出来,直到找到 [=12=] 。很可能在缓冲区中找不到 [=12=],在这种情况下它将继续读取,可能在分配的内存之外并因此崩溃。
  • 您假设 Python 中的 send 会发送完整的消息,但这并不能保证。检查 send 的 return 值实际发送了多少或使用 sendall.
  • 您假定 C 中的 recv 会收到完整的消息,但这并不能保证。 TCP 没有消息的概念,recv 将 return 只是 return 已经收到的字节。特别是对于大消息或小 TCP windows,这可能不是您想要的完整消息。