如何将消息从 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,这可能不是您想要的完整消息。
我有一个 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,这可能不是您想要的完整消息。