C#多个tcpclients同时

时间:2015-10-31 16:23:26

标签: c# sockets tcpclient tcplistener tcpserver

我已经在msdn页面上关注了tcpclient和tcplistener示例:https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

我正在尝试连接到我有tcp echo服务器的几个硬件。我可以创建一个tcpclient并连接到一个板,并发送和接收具有毫秒延迟的回声全孔。我可以通过毫秒延迟连接到第二块板。我无法同时连接到两个主板并发送带有响应的字符串,即使我只执行了一次这样的操作并返回循环。

我基本上采用了异步客户端示例并添加了一些代码来使用按钮激活它:

    private void button1_Click(object sender, EventArgs e)
    {
        AsynchronousClient client1 = new AsynchronousClient();
        AsynchronousClient client2 = new AsynchronousClient();

        client1.Begin("192.168.1.10");
        Thread.Sleep(5000);
        client2.Begin("192.168.1.11");
    }

这段代码死了。最后,我希望能够连接到我的硬件的几个部分并每隔一秒左右发送请求以查询他们可能已累积的数据。我不认为我理解tcp足以使这项工作,但我认为我应该能够异步地与两个客户端交谈。我尝试用线程,任务和我能想到的任何其他东西来实现它,但我无法与我的应用程序同时与两台服务器进行可靠的通信。任何见解都会有所帮助谢谢。

编辑:

这是我现在正在使用的内容。这是一种安全的方法吗?我还没有写任何错误处理。此外,我是一名硬件工程师,并不住在c#世界,我正在努力学习如何正确使用这种语言。

using System;
using System.Net.Sockets;
using System.Diagnostics;
using System.Threading;
using System.Collections.Generic;
using System.Linq;

namespace Swordfish
{
    class SwordfishClient
    {
        private static ManualResetEvent connectDone = new ManualResetEvent(false);
        private static ManualResetEvent sendDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveSizeDone = new ManualResetEvent(false);
        private static ManualResetEvent receiveMessageDone = new ManualResetEvent(false);
        private static ManualResetEvent parsedDataDone = new ManualResetEvent(false);

        Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        byte[] Size = new byte[2];
        byte[] Message = new byte[1024];

        public event Action<InPacket> NewPacket;

        public void Connect(string address, int port)
        {
            if (!client.Connected)
            {
                try
                {
                    client.BeginConnect(address, port, new AsyncCallback(ConnectCallback), client);
                    connectDone.WaitOne();
                }
                catch
                {
                    return;
                }
            }
        }

        public void SendMessage(byte[] data)
        {
            if (client.Connected)
            {
                sendDone.Reset();
                client.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), client);      
                Trace.WriteLine("Waiting on SendCallback: " + sendDone.WaitOne());

                receiveSizeDone.Reset();
                client.BeginReceive(Size, 0, 2, 0, new AsyncCallback(ReceiveSizeCallback), client);                          
                Trace.WriteLine("Waiting on ReceiveSizeCallback: " + receiveSizeDone.WaitOne());

                receiveMessageDone.Reset();
                client.BeginReceive(Message, 0, BitConverter.ToUInt16(Size, 0), 0, new AsyncCallback(ReceiveMessageCallback), client);               
                Trace.WriteLine("Waiting on ReceiveMessageCallback: " + receiveMessageDone.WaitOne());

                parsedDataDone.Reset();
                parsePacket(Message, BitConverter.ToUInt16(Size, 0));
                parsedDataDone.WaitOne();         
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            Socket client = (Socket)ar.AsyncState;
            client.EndConnect(ar);
            connectDone.Set();
        }

        private static void ReceiveSizeCallback(IAsyncResult ar)
        {
            Socket client = (Socket)ar.AsyncState;
            int bytesRead = client.EndReceive(ar);

            Trace.WriteLine("-------------------");
            Trace.WriteLine("Received Header Size: " + bytesRead);

            if (bytesRead > 0)
            {
                receiveSizeDone.Set();
            }
        }

        private static void ReceiveMessageCallback(IAsyncResult ar)
        {
            Socket client = (Socket)ar.AsyncState;
            int bytesRead = client.EndReceive(ar);

            Trace.WriteLine("-------------------");
            Trace.WriteLine("Received Message Size: " + bytesRead);

            if (bytesRead > 0)
            {
                receiveMessageDone.Set();
            }
        }

        private static void SendCallback(IAsyncResult ar)
        {
            Socket client = (Socket)ar.AsyncState;
            int bytesSent = client.EndSend(ar);
            Trace.WriteLine("-------------------");
            Trace.WriteLine("Bytes Sent: " + bytesSent);
            sendDone.Set();
        }

        private void parsePacket(byte[] data, int size)
        {
            Queue<byte> receivedBytes = new Queue<byte>();
            for (int i = 0; i < size - 2; i++)
            {
                receivedBytes.Enqueue(data[i]);
            }

            byte[] statusBytes = Enumerable.Range(0, 2).Select(i => receivedBytes.Dequeue()).ToArray();
            StatusCode status = (StatusCode)Enum.ToObject(typeof(StatusCode), BitConverter.ToUInt16(statusBytes, 0));

            byte[] messageBytes = Enumerable.Range(0, size - 4).Select(i => receivedBytes.Dequeue()).ToArray();

            NewPacket.Invoke(new InPacket(status, messageBytes));


            Trace.WriteLine("-------------------");
            Trace.WriteLine("Size: " + size);
            Trace.WriteLine("-------------------");
            Trace.WriteLine("Status: " + status);
            Trace.WriteLine("-------------------");

            for (int i = 0; i < data.Length; i++)
            {
                Trace.Write(data[i] + " ");
                if (i> 0 && i % 75 == 0)
                    Trace.WriteLine("");

                if(i == size - 2)
                    Trace.WriteLine("\r\n----------End of Message: This should all be zero------");
            }
            Trace.WriteLine("\r\n----------------------------------------------------------\r\n");

            for(int i =0; i < Message.Length; i++)
            {
                Message[i] = 0;
            }

            parsedDataDone.Set();
        }
    }
}

Took 7.5514 milliseconds to connect.
-------------------
Bytes Sent: 2
Waiting on SendCallback: True
-------------------
Received Header Size: 2
Waiting on ReceiveSizeCallback: True
-------------------
Received Message Size: 236
Waiting on ReceiveMessageCallback: True
-------------------
Size: 238
-------------------
Status: STATUS_LOG
-------------------
6 0 3 91 69 84 72 69 82 78 69 84 93 32 65 99 99 101 112 116 101 100 32 99 111 110 110 101 99 116 105 111 110 32 102 114 111 109 32 49 48 46 54 52 46 49 46 49 48 58 50 52 53 48 57 32 45 62 32 112 111 114 116 32 53 48 48 48 48 10 23 3 91 69 84 72 
69 82 78 69 84 93 32 65 99 99 101 112 116 101 100 32 99 111 110 110 101 99 116 105 111 110 32 102 114 111 109 32 49 48 46 54 52 46 49 46 49 48 58 50 52 53 49 48 32 45 62 32 112 111 114 116 32 53 48 48 48 49 10 23 3 91 69 84 72 69 82 78 69 84 93 
32 84 114 121 105 110 103 32 116 111 32 99 111 110 110 101 99 116 32 116 111 32 49 48 46 54 52 46 49 46 49 48 58 53 48 48 48 50 10 23 1 91 114 101 99 118 95 99 97 108 108 98 97 99 107 93 32 103 111 116 32 50 32 98 121 116 101 115 32 111 110 32 99 111 110 
102 105 103 32 112 111 114 116 10 23 0 
----------End of Message: This should all be zero------
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
----------------------------------------------------------

[ETHERNET] Accepted connection from 10.64.1.10:24509 -> port 50000
[ETHERNET] Accepted connection from 10.64.1.10:24510 -> port 50001
[ETHERNET] Trying to connect to 10.64.1.10:50002
[recv_callback] got 2 bytes on config port

1 个答案:

答案 0 :(得分:0)

该代码可能会死,因为当此方法结束时,这些客户端变量超出范围,并且在某些时候它们被垃圾回收器回收。您还应该显示服务器代码以查看是否有任何可疑的内容。

看看这个TCP通信示例:https://github.com/vtortola/AynchronousTCPListener

我希望你觉得它很有用。