【发布时间】:2015-07-02 16:14:52
【问题描述】:
我正在尝试使用套接字和内存流通过网络发送一些文本。我的示例中的完整数据长度为 20480 字节。缓冲区大小为 8192。 在我接收到最后的 4096 个字节之前,套接字只接收到了 3088 个字节,整个线程在接收到最后一块数据之前没有抛出异常就退出了。
// Send
while (sentBytes < ms.Length)
{
if (streamSize < Convert.ToInt64(buffer.Length))
{
ms.Read(buffer, 0, Convert.ToInt32(streamSize));
count = socket.Send(buffer, 0, Convert.ToInt32(streamSize), SocketFlags.None);
sentBytes += Convert.ToInt64(count);
streamSize -= Convert.ToInt64(count);
}
else
{
ms.Read(buffer, 0, buffer.Length);
count = socket.Send(buffer, 0, buffer.Length, SocketFlags.None);
sentBytes += Convert.ToInt64(count);
streamSize -= Convert.ToInt64(count);
}
}
// Receive
while (readBytes < size)
{
if (streamSize < Convert.ToInt64(buffer.Length))
// exits after this, before receiving the last 1008 bytes
{
count = socket.Receive(buffer, 0, Convert.ToInt32(streamSize), SocketFlags.None);
if (count > 0)
{
ms.Write(buffer, 0, count);
readBytes += Convert.ToInt64(count);
streamSize -= Convert.ToInt64(count);
}
}
else
{
count = socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
if (count > 0)
{
ms.Write(buffer, 0, count);
readBytes += Convert.ToInt64(count);
streamSize -= Convert.ToInt64(count);
}
}
}
我使用完全相同的算法来发送/接收更大尺寸(超过 1 GB)的文件,并且传输工作完美,没有文件损坏(为此我使用文件流)。 有趣的是,如果我在发送方添加断点,则此代码可以在调试器中运行。
也适用于这种修改:
if (streamSize < Convert.ToInt64(buffer.Length))
{
if (count > 0)
{
ms.Write(buffer, 0, Convert.ToInt32(streamSize));
readBytes += streamSize;
streamSize -= streamSize;
}
}
但这并没有检查接收到的数据量,也无法传输文件。 谁能指出这里发生了什么?
线程是这样开始的:
public ClientConnection(Socket clientSocket, Server mainForm)
{
this.clientSocket = clientSocket;
clientThread = new Thread(ReceiveData);
clientConnected = true;
this.mainForm = mainForm;
clientThread.Start(clientSocket);
}
由 OP 评论添加
// text is 10240 characters long
MemoryStream ms = new MemoryStream(UnicodeEncoding.Unicode.GetBytes(text));
// streamsize is 20480, which is sent prior to text in a header to the receiver
long streamSize = ms.Length;
更新: 测试了更多文件,现在文件传输也失败了。问题在于所有情况下的最后 1008 个字节。
【问题讨论】:
-
你是怎么得到那段代码的。你是如何启动你的线程的?
-
streamSize如何计算? -
// 文本长度为 10240 个字符 MemoryStream ms = new MemoryStream(UnicodeEncoding.Unicode.GetBytes(text)); // streamsize 为 20480,在 header 中的文本之前发送给接收者 long streamSize = ms.Length;
-
@Laz80UK - 将来,请编辑您的问题以添加代码,因为代码在 cmets 中的格式不正确并且难以阅读/遵循。
-
是的,我想到了。第一次使用这里,感谢您帮助我。 :)
标签: c# multithreading sockets memorystream