2013-11-20 81 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是正确的 - 通过不忽略()由读返回的结果修复它。 –