首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有C#线程的TcpClient消息(各种错误)

带有C#线程的TcpClient消息(各种错误)
EN

Stack Overflow用户
提问于 2014-10-21 13:25:21
回答 2查看 338关注 0票数 0

我需要通过TCP连接发送500条消息,并在有限的时间内为每条消息接收一个响应,使用线程保持在时间内。这对我来说是新的,我花了很多时间在论坛上搜索,然后才把它放在这里,所以请耐心点。

到目前为止,我得到的最好结果是:

代码语言:javascript
复制
List<Task> tasks = new List<Task>();
for(int i=1;i<500;i++)
{
    Task task = new Task(new SendMessage(Message(i)).Send);
    tasks.Add(task);
}

然后

代码语言:javascript
复制
foreach(Task task in tasks)
{
    task.Start();
}

// Keep track of time (stay within 30s)
Stopwatch s = new Stopwatch();
s.Start();
while (s.ElapsedMilliseconds < 30000)
{
    Console.WriteLine((int)(0.001 * s.ElapsedMilliseconds));
    Thread.Sleep(2000);
}

然后

代码语言:javascript
复制
public class SendMessage
{
    byte[] msg;
    ASCIIEncoding asen = new ASCIIEncoding();
    NetworkStream stm;

    public void Send()
    {
        try
        {
            TcpClient tcpclnt = new TcpClient();

            tcpclnt.Connect("IPADDRESS", port);

            stm = tcpclnt.GetStream();

            stm.Write(msg, 0, msg.Length);

            using (XmlReader xmlReader = XmlReader.Create(stm))
            {
                while (xmlReader.Read())
                {
                    string requestID = String.Empty;
                    string message = String.Empty;

                    if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "requestID"))
                    {
                        requestID = xmlReader.ReadInnerXml();
                        sw.Write("requestID\t" + requestID + "\t");
                        Console.WriteLine("requestID\t" + requestID + "\t");
                    }
                    else if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "message"))
                    {
                        message = xmlReader.ReadInnerXml();
                        sw.WriteLine("message\t" + message);
                        Console.WriteLine("message\t" + message);

                        xmlReader.Close();
                    }
                }
            }
        }
        catch
        {
            Send();
        }
    }
    public SendMessage(  string msg)
    {
        this.msg = asen.GetBytes(msg);  
    }
}

但是应用程序在阅读部分不断崩溃。在这个例子中我得到的错误是

XMLException -根元素丢失

try/catch块似乎工作正常,但是错误非常频繁,以至于应用程序速度慢到我无法接受时间消耗的程度。

我试过的变体

  1. 使用全局静态TCPClient连接Main而不是Send()
  2. 在NetworkStream中使用SendMessage中的全局或本地
  3. 解析TCPClient作为参考
  4. 使用线程而不是任务
  5. 使用其他线程安全读取器类型(当使用线程时)
EN

回答 2

Stack Overflow用户

发布于 2014-10-21 13:36:08

在TCP连接中,可以同时向套接字发送或接收套接字,但不能从每个线程发送或接收。

最好使用生产者/消费者模式,这样您就可以在消息到达时不等待地发送并得到通知:如何:实现生产者-消费者数据流模式

此外,您还需要一些框架协议来通过套接字发送东西,让另一端知道消息从哪里开始或结束。这就是为什么缺少文件的一部分。

我建议您看一下WCF:[ .NET Framework4.0](http://msdn.microsoft.com/en-us/library/dd456779(v=vs.110%29.aspx)

票数 2
EN

Stack Overflow用户

发布于 2014-10-21 14:19:40

我相信你现在面临的问题是,在你从溪流中读到信息之前,你不会等待回应。这里接受的答案显示了如何在阅读之前等待响应。虽然还有其他的复杂性需要考虑,但这应该可以解决您当前的问题。如果您的消息很大(超过1.5KB,或者您的默认mtu大小),仅仅因为您在套接字上收到了一些数据,并不意味着您已经收到了套接字上的所有数据。因此,您需要为您的XML响应设置某种框架。您是否考虑过查看WCF或web服务生产者/消费者?

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

https://stackoverflow.com/questions/26487857

复制
相关文章

相似问题

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