我有一個在以下代碼上運行的 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 。
客戶端.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;
}
};
客戶端.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')在接收時首先解碼訊息。我該如何解決?
uj5u.com熱心網友回復:
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]) 上的緩沖區中。該緩沖區將在函式退出后自動釋放,因此您從函式回傳的內容不再存在。 - 列印時,您將訊息視為
\0-terminated char[] 即使它沒有\0終止。這意味著接收訊息之后的垃圾將被列印,直到\0找到。很可能\0在緩沖區中找不到任何東西,在這種情況下它將繼續讀取,可能在分配的記憶體之外并因此崩潰。 - 您假設
sendPython 中的 將發送完整的訊息,但這不能保證。send檢查實際發送或使用多少的回傳值sendall。 - 您假設
recv在 C 中將收到完整的訊息,但這不能保證。TCP 沒有訊息的概念,recv只會回傳已經收到的位元組。特別是對于大訊息或小 TCP 視窗,這可能不是您想要的完整訊息。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/421474.html
標籤:
上一篇:如何連續運行例程,直到在命令列中輸入輸入?-Python
下一篇:套接字系結名稱之間的區別
