C# 在TCPSocket中发送多个数据

C# 在TCPSocket中发送多个数据,c#,network-programming,tcpclient,C#,Network Programming,Tcpclient,我正在尝试使用TCPSocket创建一个带有文件传输的聊天应用程序,下面是我的代码 发件人: public void sendData(string message) { StreamWriter streamWriter = new StreamWriter(netStream); // netStream is // connected strea

我正在尝试使用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


无论如何,我可以只使用1个套接字或连接发送文件并同时发送聊天吗。。?或者每次发送文件时都需要使用新的套接字连接。

您会得到一个无限循环,因为只有在到达流的末尾时才会返回
null
。对于网络流,“流结束”表示“另一端已关闭其连接的一半”。由于另一端是您的客户机,它在等待用户输入更多数据时保持连接打开,因此最终将出现一个无限循环

相反,您要做的是启动一个操作,该操作只有在有更多数据要读取时才能完成。有两种方法可以做到这一点:要么使用阻塞读取操作(在专用线程上,这样在等待消息时不会阻塞应用程序的其他处理),要么使用异步(基于事件或回调)方法

对于同步(阻塞)方法,请参阅文档,其中包含示例代码,说明如何检查是否有传入数据以及如何读取数据。这里您绝对需要知道的一点是,当
Read
返回零时,这意味着所有数据都已读取,并且连接已从另一端关闭(因此您也应该关闭端,而不是循环;客户端已断开连接)

对于低级异步网络读取,相关的操作是,它有自己的示例

这两种方法的级别都低于您当前拥有的级别,需要您在缓冲区内手动组装数据,并决定何时积累了“足够的数据”(即整行数据)供您处理。然后,您必须小心地将该数据从缓冲区中拉出并继续

对于仍然允许您进行某种程度的编排的更高级别方法,请查看(特别是其中的两个同步和异步选项)。此功能由类(以及相应的服务器端)引入


最后,正如jValdron的评论所说,您要么需要一个单独的连接来传输文件数据,要么设计一些自定义协议,允许您在同一网络流上交错多种数据。第二种解决方案通常具有更高的技术优势,但也更难正确实现。

您会得到一个无限循环,因为只有在到达流的末尾时才会返回
null
。对于网络流,“流结束”表示“另一端已关闭其连接的一半”。由于另一端是您的客户机,它在等待用户输入更多数据时保持连接打开,因此最终将出现一个无限循环

相反,您要做的是启动一个操作,该操作只有在有更多数据要读取时才能完成。有两种方法可以做到这一点:要么使用阻塞读取操作(在专用线程上,这样在等待消息时不会阻塞应用程序的其他处理),要么使用异步(基于事件或回调)方法

对于同步(阻塞)方法,请参阅文档,其中包含示例代码,说明如何检查是否有传入数据以及如何读取数据。这里您绝对需要知道的一点是,当
Read
返回零时,这意味着所有数据都已读取,并且连接已从另一端关闭(因此您也应该关闭端,而不是循环;客户端已断开连接)

对于低级异步网络读取,相关的操作是,它有自己的示例

这两种方法的级别都低于您当前拥有的级别,需要您在缓冲区内手动组装数据,并决定何时积累了“足够的数据”(即整行数据)供您处理。然后,您必须小心地将该数据从缓冲区中拉出并继续

对于仍然允许您进行某种程度的编排的更高级别方法,请查看(特别是其中的两个同步和异步选项)。此功能由类(以及相应的服务器端)引入


最后,正如jValdron的评论所说,您要么需要一个单独的连接来传输文件数据,要么设计一些自定义协议,允许您在同一网络流上交错多种数据。第二种解决方案通常具有更高的技术优势,但这也会使您更难正确实现。

查看BasicSend示例,其中演示了使用开源库的简单聊天应用程序。

查看BasicSend示例,其中演示了使用开源库的简单聊天应用程序。

如果发送一个大文件,您应该使用两个套接字,它将阻止聊天,除非您在每个数据包上找到一个检测它是对话还是文件的另一部分的头。您应该使用2个套接字,如果您发送一个大文件,它将阻止聊天,除非您在每个数据包上找到一个检测它是对话还是文件的另一部分的头。