2012-02-20 121 views
1

我有服務器和客戶端通過Windows套接字發送/接收字符串。Sendto()套接字方法發送短字符串垃圾

客戶端代碼(發件人):

string c = "Haha"; 

sprintf(temp.Buffer, c.c_str()); 
temp.len = c.size(); 
int sent = 0; 
if ((sent = sendto(s, temp.Buffer, temp.len + 1, 0, (SOCKADDR*)&sa_in, sizeof(sa_in))) == SOCKET_ERROR) { 
    cout << "Send request method failed\n"; 
} 

服務器代碼(接收器):

if (!(outfds = select (1 , &readfds, NULL, NULL, NULL))) {//timed out 
    cout << "timed out"; 
} 
if (outfds == 1) 
{ 
    fromlen = sizeof sa_in; 
    received = recvfrom(s, buf, 2048, 0, (struct sockaddr*)&sa_in, &fromlen); 
} 

在服務器中,我發現,如果我從客戶端發送字符串比小字節數(如0-8〜)'buf'變量在其末尾包含垃圾。例如,我將發送字符串「ahah」,服務器將收到類似「ahah0」的字符串。如果我發送「Hello World」,它會正確接收它。客戶端和服務器中的字符緩衝區大小均爲2048.

我發現這個解決方案是在sendto()方法中將長度加1。如果我發送比最大允許大小更大的東西,我不希望這會在以後的a **中咬我。

有沒有人知道這是來自哪裏,你有更好的解決方案嗎?

編輯:發送和接收的字節數總是相同的。

感謝

+0

'sprintf(temp.Buffer,c.c_str());'?這是做什麼的?你確定你不是指'strcpy()'嗎? – trojanfoe 2012-02-20 23:13:54

+0

'+ 1'也會發送C字符串的''\ 0'終止符。你是否在接收器中用零值啓動了'buf'?而'sprintf(temp.Buffer,c.c_str())'提供了一種潛在的格式化字符串攻擊,使用'strncpy'或'sprintf(temp.Buffer,「%s」,c.c_str())'代替。 – Zeta 2012-02-20 23:15:24

+0

我試過用strcpy,仍然有同樣的錯誤。我沒有用零值啓動buf,但對於較長的字符串會有什麼不同? – 2012-02-20 23:20:48

回答

2

你是不是發射後'\0'字符。你的協議是否指定了一個以nul結尾的字符串?如果是這樣,從而改變你的客戶:

sendto(..., temp.len+1, ...); 

如果你的協議規定,你不發送NUL終止,然後修改您的服務器這樣的:

fromlen = sizeof sa_in; 
received = recvfrom(s, buf, 2048, 0, (struct sockaddr*)&sa_in, &fromlen); 
if(received >= 0) 
    buf[received] = 0; 

如果協議沒有規定,那麼現在停止編碼並完成編寫您的協議規範。