Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用套接字进行文件传输(C)-收到的文件不包含完整数据_C#_Sockets_Bytearray - Fatal编程技术网

C# 使用套接字进行文件传输(C)-收到的文件不包含完整数据

C# 使用套接字进行文件传输(C)-收到的文件不包含完整数据,c#,sockets,bytearray,C#,Sockets,Bytearray,我使用套接字连接为文件传输创建了一个服务器和一个客户端。 我面临的问题是,如果接收到的文件大小超过8KB,则该文件是不完整的 如果您遇到了这个问题,您能否指导我找出我在服务器/客户端犯了什么错误 以下是两种方法: 客户: 和服务器: 编辑:24.08.2012我已设法找出问题并使服务器正常工作 服务器的完整代码为: 服务器: 发件人: Receive方法将读取尽可能多的可用数据,最多读取size参数指定的字节数 它不能保证一次阅读所有内容;它可以读取最多可读取的内容,以达到您的情况下缓冲区的最大

我使用套接字连接为文件传输创建了一个服务器和一个客户端。 我面临的问题是,如果接收到的文件大小超过8KB,则该文件是不完整的

如果您遇到了这个问题,您能否指导我找出我在服务器/客户端犯了什么错误

以下是两种方法:

客户:

和服务器:

编辑:24.08.2012我已设法找出问题并使服务器正常工作 服务器的完整代码为: 服务器:

发件人:

Receive方法将读取尽可能多的可用数据,最多读取size参数指定的字节数

它不能保证一次阅读所有内容;它可以读取最多可读取的内容,以达到您的情况下缓冲区的最大大小。当从任何流读取时,通常需要有一个读/接收循环。在您的情况下,我认为缓冲区的大小过大,您应该手动读取长度字节,然后在一个小缓冲区上进行读取/接收循环,比如4096字节,用于文件处理。您不需要512k缓冲区

经典的读/接收循环是:

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和混合数据包顺序下: