我正在尝试使用TCPSocket创建与文件传输应用程序的聊天,这是我的代码..
SENDER:
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();
}
RECEIVER:
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吗?
无论如何,我可以只使用1个套接字或连接来发送文件并同时发送聊天..?或者我每次发送文件时都需要使用新的套接字连接..
答案 0 :(得分:1)
你得到一个无限循环,因为StreamReader.ReadLine
只会在到达流末尾时返回null
。对于网络流,“流结束”表示“另一方已关闭其连接的一半”。由于另一方是您的客户端,并且在等待用户输入更多数据时保持连接打开,因此您将最终获得无限循环。
您要做的是取消仅在有更多数据要读取时才完成的操作。有两种方法:使用阻塞读取操作(在专用线程上,以便在等待消息时不阻止应用程序的其他处理),或使用异步(基于事件或回调)方法
对于同步(阻塞)方法,请参阅NetworkStream.Read
上的文档,其中包含示例代码,该代码显示了如何检查是否有传入数据以及如何读取它。这里你绝对需要知道的一点是,当Read
返回零时,表示所有数据都已被读取,连接已从另一侧关闭(所以你也应该关闭你的结束而不是循环;客户已断开连接。)
对于低级异步网络读取,相关操作为NetworkStream.BeginRead
,附带自己的示例。
这两种方法都比您现有的方法更低,并且需要您在缓冲区内手动组装数据,并决定何时累积“足够的数据”(即整行)以供您处理。然后,您必须小心地将该数据从缓冲区中拉出并继续。
对于仍然允许您进行某种程度协调的更高级别方法,请查看using client sockets(特别是那里的两个同步和异步选项)。此功能由TcpClient
(以及服务器端对应的TcpListener
)类引入。
最后,正如jValdron的评论所说,您将需要一个单独的连接来传输文件数据或设计一些自定义协议,允许您在同一网络流上交错多种数据。第二种解决方案通常具有更多技术优势,但您也难以正确实施。
答案 1 :(得分:0)
查看networkComms.net中的BasicSend示例,演示使用开源库的简单聊天应用程序。