2013-11-20 82 views
1

我想從一個Python服務器發送一個長字符串到C#客戶端。該字符串長230400個字節。我都是以64字節爲單位發送和接收的。服務器代碼:Python到C#TCP傳輸損壞超過1523rd字節的數據

import socket 

def initialize(): 
    global s 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    s.bind(('', 1719)) 
    s.listen() 

initialize() 

while(1): 
    sock, addr = s.accept() 

    msgstr = generate_msg_string() # irrelevant 

    msglen = len(msgstr) 

    totalsent = 0 
    while totalsent < msglen: 
    sent = sock.send(msgstr[totalsent:totalsent+64]) 
    totalsent = totasent + sent 

    sock.close() 

客戶端代碼:

TcpClient tcpClient = new TcpClient(); 
tcpClient.Connect(ip, 1719); 
byte[] ba = new byte[230400]; 
byte[] buffer = new byte[64]; 
tcpClient.ReceiveBufferSize = 64 
int i=0; 
while(i != 230400) 
{ 
    stream.Read(buffer, 0, 64); 
    buffer.CopyTo(ba, i); 
    i += 64; 
} 
tcpClient.Close(); 

我連續查了幾個連接 - 第1523個字節是正確的,其他都是廢話 - 至少看似隨意。

任何想法可能是什麼原因?

回答

3
while(i != 230400) 
{ 
    stream.Read(buffer, 0, 64); 
    buffer.CopyTo(ba, i); 
    i += 64; 
} 

這裏的基本錯誤是假設Read讀取64個字節。如果套接字被關閉以任何理由

  • 64字節,如果出現這種情況可用

    • 0,它選擇
    • 1-63個字節,只是爲了好玩
    • :它可以讀取任何的

    「如果流已關閉非陽性,否則至少1個字節,不超過64個字節」你不能保證比其他任何

    必須必須讀取Read的返回值,並且只處理那麼多的緩衝區。順便說一下,如果您切換到Socket.Receive,則仍然如此。

    另外 - 爲什麼你不只是填寫ba首先,增加偏移量和減少每次計數?

    int count = 230400, offset = 0, read; 
    byte[] ba = new byte[count]; 
    while(count > 0 && (read=stream.Read(ba, offset, count)) > 0) 
    { 
        offset += read; 
        count -= read; 
    } 
    if(read!=0) throw new EndOfStreamException(); 
    
  • +0

    這確實有幫助。我收到的字符串現在完全正確。謝謝! – Lasooch

    0

    看來我趕緊提問了。

    將TcpClient更改爲套接字修復了此問題。該方法保持不變。

    +2

    這種方法是很破... –

    +0

    @MarcGravell是正確的 - 通過不忽略()由讀返回的結果修復它。 –