首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在TCPSocket中发送多个数据

在TCPSocket中发送多个数据
EN

Stack Overflow用户
提问于 2011-12-03 03:21:12
回答 2查看 1.2K关注 0票数 1

我正在尝试使用TCPSocket创建一个带有文件传输应用程序的聊天,下面是我的代码。

发件人:

代码语言:javascript
复制
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();
}

接收者:

代码语言:javascript
复制
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()
}

问题是我总是在这条语句中变成无限循环

代码语言:javascript
复制
while ((data = streamReader.ReadLine()) != null)
{
    dataAppends.Append(data);
}

即使我把streamWriter.Flush()放在我的发送器上..

是否需要关闭/处置netStream/NetworkStream?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-12-03 03:39:12

您会得到一个无限循环,因为StreamReader.ReadLine只会在到达流的末尾时返回null。对于网络流来说,“结束流”意味着“对方已经关闭了自己的那一半连接”。由于另一端是您的客户端,并且它在等待用户键入更多数据时保持连接打开,因此您将以无限循环结束。

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

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

对于底层异步网络读取,相关操作为NetworkStream.BeginRead,自带示例。

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

对于仍然允许您在一定程度上进行编排的更高级别的方法,请查看using client sockets (特别是那里的两个同步和异步选项)。此功能是由TcpClient (以及服务器端相应的TcpListener)类引入的。

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

票数 1
EN

Stack Overflow用户

发布于 2011-12-19 05:16:31

查看networkComms.net中的BasicSend示例,该示例演示了一个使用开源库的简单聊天应用程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8361448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档