我有一段接收的程序 s.Send(Encoding.Default.GetBytes("sendfile"));
Array.Resize(ref bytes, n);
s.ReceiveBufferSize = n;
s.Receive(bytes, n, 0);
System.IO.FileStream f = new System.IO.FileStream("tmp.jpg", System.IO.FileMode.Create, System.IO.FileAccess.Write);
f.Write(bytes, 0, n);
f.Close();约定好接收N个字节,其实是一个图形文件的大小,用s.Receive(bytes, n, 0)收数据后,把Bytes中的文件写到磁盘再画出来,有时候会发现图像的下半截没有,为什么?
但是我用下面的语句就没发现少数据的问题了 s.Send(Encoding.Default.GetBytes("sendfile"));
Array.Resize(ref bytes, n);
s.ReceiveBufferSize = n;
for (int i = 0; i < 1000; i++)
{
Application.DoEvents();
System.Threading.Thread.Sleep(10);
if (s.Available >= n) break; }
s.Receive(bytes, n, 0);
System.IO.FileStream f = new System.IO.FileStream("tmp.jpg", System.IO.FileMode.Create, System.IO.FileAccess.Write);
f.Write(bytes, 0, n);
f.Close();就是在接收前加一段延时,就能把数据收完整了。我的疑问是s.Receive(bytes, n, 0)方法,本来不就应会等到N个数据才会返回吗?那段延时按道理是没有意义的吗?
我的Socket设置了12秒的超时,如果不写延时,无论写不写延时,均未发现超时.
Array.Resize(ref bytes, n);
s.ReceiveBufferSize = n;
s.Receive(bytes, n, 0);
System.IO.FileStream f = new System.IO.FileStream("tmp.jpg", System.IO.FileMode.Create, System.IO.FileAccess.Write);
f.Write(bytes, 0, n);
f.Close();约定好接收N个字节,其实是一个图形文件的大小,用s.Receive(bytes, n, 0)收数据后,把Bytes中的文件写到磁盘再画出来,有时候会发现图像的下半截没有,为什么?
但是我用下面的语句就没发现少数据的问题了 s.Send(Encoding.Default.GetBytes("sendfile"));
Array.Resize(ref bytes, n);
s.ReceiveBufferSize = n;
for (int i = 0; i < 1000; i++)
{
Application.DoEvents();
System.Threading.Thread.Sleep(10);
if (s.Available >= n) break; }
s.Receive(bytes, n, 0);
System.IO.FileStream f = new System.IO.FileStream("tmp.jpg", System.IO.FileMode.Create, System.IO.FileAccess.Write);
f.Write(bytes, 0, n);
f.Close();就是在接收前加一段延时,就能把数据收完整了。我的疑问是s.Receive(bytes, n, 0)方法,本来不就应会等到N个数据才会返回吗?那段延时按道理是没有意义的吗?
我的Socket设置了12秒的超时,如果不写延时,无论写不写延时,均未发现超时.
我怎么感觉画蛇添足啊。关于你那个问题,估计就是你的ReceiveBufferSize太大的缘故了,如果数据不是一次性连续读入,中间有断续,它就读不完ReceiveBufferSize的大小就返回了,你需要下次继续读取。其实何必如此呢,你完全可以设置个小点的Buffer,比如1024。然后循环读取,判断读取的总长度正好为文件长度,就停止接收。
送完数据记得压出啊,压出啊!Flush之TCP(在半双工模式下),网卡会维持一个缓冲区,网卡设备认为合适的时候,就会发出。而不是你把数据灌进去的时候他就发出(简单的说Socket象网卡里灌数据,不代表网卡“立刻”发出去了)某些数据会在下一个tcp包里发送。明白了?嗯,全双工模式更复杂一点,不过好在Socket代码操作没有任何区别。
那个n就是文件的大小啊,要传的文件长度事先又不知道,不用Array.Resize你说怎么办?又怎么会画蛇添足呢?我看了MSDN 关于Socket.Receive的介绍,如果在Receive中指定了要接收的字节数,Receive会等到字节数够了才返回的,难道Msdn说的不对?如果没接收完就返回,那和不指定字节数的那个重载又和分别?