在TCPSocket中发送多个数据
本文关键字:数据 TCPSocket | 更新日期: 2023-09-27 18:16:25
我正在尝试使用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()放在我的sender.
我需要关闭/处理netStream/NetworkStream吗?
无论如何,我可以只使用1套接字或连接发送文件和发送聊天在同一时间…?或者我需要使用一个新的套接字连接每次我发送一个文件..
你会得到一个无限循环,因为StreamReader.ReadLine
只会在到达流的末尾时返回null
。对于网络流来说,"流的结束"意味着"另一方已经关闭了它那一半的连接"。由于另一端是您的客户端,它在等待用户输入更多数据时保持连接打开,因此您将以无限循环结束。
你想做的是触发一个操作,只有当有更多的数据要读时才完成。有两种方法可以做到这一点:要么使用阻塞读操作(在专用线程上,这样在等待消息时就不会阻塞应用程序的其他处理),要么使用异步(基于事件或回调)方法。
对于同步(阻塞)方法,请参阅NetworkStream.Read
上的文档,其中包括演示如何检查是否有传入数据以及如何读取数据的示例代码。这里你绝对需要知道的一点是,当Read
返回零时,这意味着所有的数据已经被读取,连接已经从另一边关闭(所以你也应该关闭你的端,而不是循环;
对于低级异步网络读,相关的操作是NetworkStream.BeginRead
,它有自己的示例。
这两种方法都比你目前拥有的更低级,并且需要你手动在缓冲区内组装数据,并决定何时"足够的数据"(即整行)已经积累供你处理。然后,您必须小心地将该数据从缓冲区中取出并继续。
对于仍然允许某种程度的编排的高级方法,请考虑使用客户端套接字(特别是其中的两个同步和异步选项)。此功能由TcpClient
(以及服务器端相应的TcpListener
)类引入。
最后,正如jValdron的评论所说,您要么需要一个单独的连接来传输文件数据,要么设计一些自定义协议,允许您在同一网络流上交错传输多种数据。第二种解决方案通常具有更多的技术优点,但对您来说,正确实现它也更加困难。
查看networkComms.net中的BasicSend示例,该示例演示了一个使用开源库的简单聊天应用程序。