C# 使用套接字进行文件传输(C)-收到的文件不包含完整数据
我使用套接字连接为文件传输创建了一个服务器和一个客户端。 我面临的问题是,如果接收到的文件大小超过8KB,则该文件是不完整的 如果您遇到了这个问题,您能否指导我找出我在服务器/客户端犯了什么错误 以下是两种方法: 客户: 和服务器: 编辑:24.08.2012我已设法找出问题并使服务器正常工作 服务器的完整代码为: 服务器: 发件人: Receive方法将读取尽可能多的可用数据,最多读取size参数指定的字节数 它不能保证一次阅读所有内容;它可以读取最多可读取的内容,以达到您的情况下缓冲区的最大大小。当从任何流读取时,通常需要有一个读/接收循环。在您的情况下,我认为缓冲区的大小过大,您应该手动读取长度字节,然后在一个小缓冲区上进行读取/接收循环,比如4096字节,用于文件处理。您不需要512k缓冲区 经典的读/接收循环是:C# 使用套接字进行文件传输(C)-收到的文件不包含完整数据,c#,sockets,bytearray,C#,Sockets,Bytearray,我使用套接字连接为文件传输创建了一个服务器和一个客户端。 我面临的问题是,如果接收到的文件大小超过8KB,则该文件是不完整的 如果您遇到了这个问题,您能否指导我找出我在服务器/客户端犯了什么错误 以下是两种方法: 客户: 和服务器: 编辑:24.08.2012我已设法找出问题并使服务器正常工作 服务器的完整代码为: 服务器: 发件人: Receive方法将读取尽可能多的可用数据,最多读取size参数指定的字节数 它不能保证一次阅读所有内容;它可以读取最多可读取的内容,以达到您的情况下缓冲区的最大
int read;
byte[] buffer = new byte[4096];
while((read = socket.Receive(buffer)) > 0) {
output.Write(buffer, 0, read);
}
发件人:
Receive方法将读取尽可能多的可用数据,最多读取size参数指定的字节数
它不能保证一次阅读所有内容;它可以读取最多可读取的内容,以达到您的情况下缓冲区的最大大小。当从任何流读取时,通常需要有一个读/接收循环。在您的情况下,我认为缓冲区的大小过大,您应该手动读取长度字节,然后在一个小缓冲区上进行读取/接收循环,比如4096字节,用于文件处理。您不需要512k缓冲区
经典的读/接收循环是:
int read;
byte[] buffer = new byte[4096];
while((read = socket.Receive(buffer)) > 0) {
output.Write(buffer, 0, read);
}
您已经陷入了最经典的套接字使用陷阱。这一点与伯克利开发的套接字概念一样古老 你看,你还没有读过这些文件: 请参见示例-返回值是多少 发送和接收方法都没有义务实际发送/接收您提供的所有数据。这就是为什么它们都返回一个“int”,描述实际发送/接收的数量。之所以采用这种设计,是因为系统的内部缓冲区有限。如果您提供要发送的999GB阵列,您的网卡在实际发送之前将如何存储该阵列 您可以看到8KB阈值的行为,可能是因为这是内部缓冲区的大小,或者可能是TCP网络数据包的最大大小。。我不记得它们有多大了,但它是围绕着这一点的 要以poperly方式发送和接收数据,必须使用某种循环,例如,在Simples表单中:
int bytesToBeSent = arr.Length;
int bytesActuallySent = 0;
while(bytesActuallySent < bytesToBeSent)
bytesActuallySent += socket.Send(arr, bytesActuallySent, bytesToSend - bytesActuallySent, ....);
和recv类似。您已经陷入了套接字使用的最经典陷阱。这一点与伯克利开发的套接字概念一样古老 你看,你还没有读过这些文件: 请参见示例-返回值是多少 发送和接收方法都没有义务实际发送/接收您提供的所有数据。这就是为什么它们都返回一个“int”,描述实际发送/接收的数量。之所以采用这种设计,是因为系统的内部缓冲区有限。如果您提供要发送的999GB阵列,您的网卡在实际发送之前将如何存储该阵列 您可以看到8KB阈值的行为,可能是因为这是内部缓冲区的大小,或者可能是TCP网络数据包的最大大小。。我不记得它们有多大了,但它是围绕着这一点的 要以poperly方式发送和接收数据,必须使用某种循环,例如,在Simples表单中:
int bytesToBeSent = arr.Length;
int bytesActuallySent = 0;
while(bytesActuallySent < bytesToBeSent)
bytesActuallySent += socket.Send(arr, bytesActuallySent, bytesToSend - bytesActuallySent, ....);
和recv-类似。在每次发送方法之前,您需要大约200毫秒的延迟,因为您的接收缓冲区会被传入的数据覆盖。 例如:
Thread.Sleep(200);
socket.send(sendbuffer);
在每次发送方法之前,您需要大约200毫秒的延迟,因为您的接收缓冲区被传入数据覆盖。 例如:
Thread.Sleep(200);
socket.send(sendbuffer);
发送也一样。。我想实际的问题是存在的,但当然,send和recv都必须正确处理。呵呵,这是真的,特别是在UDP和混合数据包顺序的情况下:send也是一样。。我想实际的问题是存在的,但当然发送和接收都必须正确处理。呵呵,非常正确,尤其是在UDP和混合数据包顺序下: