我正在尝试使用TCPSocket创建一个带有文件传输应用程序的聊天,下面是我的代码。
发件人:
public void sendData(string message)
{
StreamWriter streamWriter = new StreamWriter(netStream); // netStream is
// connected
streamWriter.WriteLine(message);
streamWriter.WriteLine(message);
logs.Add(string.Format("Message Sent! :{0}", message));
//netStream.Flush();
streamWriter.Flush();
}接收者:
private void ReceiveData()
{
StreamReader streamReader = new StreamReader(ChatNetStream);
StringBuilder dataAppends = new StringBuilder();
bool doneTransfer = false;
string data;
while (!doneTransfer)
{
while ((data = streamReader.ReadLine()) != null)
{
dataAppends.Append(data);
}
doneTransfer = true;
//ChatNetStream.Close();
//streamReader
}
//do whatever i want with dataAppends.ToString() here..
ReceiveData()
}问题是我总是在这条语句中变成无限循环
while ((data = streamReader.ReadLine()) != null)
{
dataAppends.Append(data);
}即使我把streamWriter.Flush()放在我的发送器上..
是否需要关闭/处置netStream/NetworkStream?
无论如何,我可以只使用一个套接字或连接来同时发送文件和聊天吗?或者每次发送文件时都需要使用新的套接字连接。
发布于 2011-12-03 03:39:12
您会得到一个无限循环,因为StreamReader.ReadLine只会在到达流的末尾时返回null。对于网络流来说,“结束流”意味着“对方已经关闭了自己的那一半连接”。由于另一端是您的客户端,并且它在等待用户键入更多数据时保持连接打开,因此您将以无限循环结束。
相反,您想要做的是启动一个仅在有更多数据要读取时才完成的操作。有两种方法可以做到这一点:要么使用阻塞读取操作(在专用线程上,这样您就不会在等待消息时阻塞应用程序的其他处理),要么使用异步(基于事件或回调)方法。
有关同步(阻塞)方法,请参阅NetworkStream.Read上的文档,其中包含示例代码,展示了如何检查是否有传入数据以及如何读取数据。这里你绝对需要知道的一点是,当Read返回零时,意味着所有数据都已被读取,连接已经从另一端关闭(所以你也应该关闭自己的一端,不要循环;客户端已经断开连接)。
对于底层异步网络读取,相关操作为NetworkStream.BeginRead,自带示例。
这两种方法都比您当前拥有的方法更低级,需要您在缓冲区内手动组装数据,并确定何时积累了“足够的数据”(即完整的行)供您处理。然后,您必须小心地将该数据从缓冲区中拉出并继续。
对于仍然允许您在一定程度上进行编排的更高级别的方法,请查看using client sockets (特别是那里的两个同步和异步选项)。此功能是由TcpClient (以及服务器端相应的TcpListener)类引入的。
最后,正如jValdron的评论所说,你要么需要一个单独的连接来传输文件数据,要么需要设计一些自定义协议,允许你在同一个网络流上交织多种类型的数据。第二种解决方案通常具有更多的技术优点,但它也会使您更难正确实现。
发布于 2011-12-19 05:16:31
查看networkComms.net中的BasicSend示例,该示例演示了一个使用开源库的简单聊天应用程序。
https://stackoverflow.com/questions/8361448
复制相似问题