C#同时有多个tcpclient

本文关键字:tcpclient | 更新日期: 2023-09-27 18:20:05

我遵循了msdn页面上的tcpclient和tcplistener示例:https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

我正在尝试连接到我有一个tcp echo服务器的几块硬件。我可以创建一个tcpclient并连接到一个板,以毫秒的延迟发送和接收一个完整的echo。我可以以毫秒的延迟自行连接到第二板。我不能同时连接到两个板并发送带有响应的字符串,即使我只这样做一次并退出循环。

我基本上以异步客户端为例,添加了一些代码来通过按钮启动它:

    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

C#同时有多个tcpclient

该代码可能会失效,因为当该方法结束时,这些客户端变量会超出范围,并在某个时候被垃圾收集器回收。您还应该显示服务器代码,看看是否有什么可疑之处。

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

我希望你觉得它有用。