C#,tcpClient到多个IP地址但在同一端口上

C#, tcpClient to Multiple IP Address but on the same port

场景:

我有多台机器,每台机器都打自己的IP,那个运行一个tcpServer,都在同一个端口。如果 tcpServer 端口打开,则在每个事务期间发送数据。它,在打开端口之前寻找客户端。

我需要什么:

我正在编写一个应用程序,它需要: 1.检查IP列表是否可用 2.为每个机器IP打开一个tcpClient端口,(都在相同的端口上) 3. 在每个指定时间后确保连接打开,如果没有重新连接。

未来:

我使用 XMl 文件提供 SQL 数据,用于获取机器列表和要侦听的端口。这里xml也是一个udp设置,如果是,那么发送的数据,必须接收并重定向到指定的UDP端口。

Class:

 public static void tcpListen(IPAddress server, int port)
        {
            try
            {
                TcpListener listener = new TcpListener(server, port);
                listener.AcceptTcpClient();
                listener.Start();

                while (true)
                {
                    Socket client = listener.AcceptSocket();

                    var childSocketThread = new Thread(() =>
                    {
                        byte[] data = new byte[100];
                        int size = client.Receive(data);
                        for (int i = 0; i < size; i++)
                        feedback = server + ":" + port + ": " + Convert.ToChar(data[i]);

                        using (StreamWriter w = File.AppendText("TCPLog.log"))
                        {
                            Log(feedback, w);
                        }
                        client.Close();
                    });
                    childSocketThread.Start();
                }
            }
            catch (Exception err)
            {
                using (StreamWriter w = File.AppendText("error.log"))
                {
                    Log("tcpControl.tcpListen: " + err.Message, w);
                }
            }
        }

每隔几秒重复的代码部分:

private void ptoCheck()
        {
            IPAddress sourceIP;
            int sourcePort;
            int destinationPort;
            string tcpStatus;
            int oldCOunt = dgvWorkstations.RowCount;
            int newCount = sqlScripts.posCount(sqlServer, sqlUser, sqlPassword, sqlDatabase);

            if (newCount != oldCOunt)
            {
                getWorkstations();
            }

            try
            {
                foreach (DataGridViewRow row in dgvWorkstations.Rows)
                {
                    int i = row.Index;
                    bool tcpState;
                    dgvWorkstations["Status", i].Value = "Checking";
                    dgvWorkstations.Refresh();
                    name = row.Cells["POS_Name"].Value.ToString();
                    sourceIP = IPAddress.Parse(row.Cells["LastKnownIP"].Value.ToString());
                    sourcePort = Convert.ToInt32(row.Cells["Receive_Port"].Value.ToString());
                    destinationPort = Convert.ToInt32(row.Cells["Send_Port"].Value.ToString());
                    tcpState = tcpControl.tcpCheck(sourceIP, sourcePort, name);

                    if (tcpState == false)
                    {
                        dgvWorkstations["Status", i].Value = "Connecting";                        
                        dgvWorkstations.Refresh();
                        tcpStatus = tcpControl.tcpConnect(sourceIP, sourcePort, name);
                        tcpControl.tcpListen(sourceIP, sourcePort);
                        dgvWorkstations["Status", i].Value = tcpStatus;
                    }

                    if (tcpState == true)
                    {
                        dgvWorkstations["Status", i].Value = "Connected";
                        dgvWorkstations.Refresh();
                    }
                    i = i + 1;
                }
            }
            catch (Exception err)
            {
                using (StreamWriter w = File.AppendText("AError.log"))
                {
                    Log("frmMain.ptoCheck: (" + name + ") " + err.Message, w);
                }
            }//End Catch
        }

我得到了下面的代码脚趾工作,从我的class我现在可以建立多个连接,但是。我调用另一个方法来侦听和接收数据的部分阻塞了第一个方法并保持它直到连接断开而不进行进一步连接。

我的Class:

public void tcpTest2(IPAddress server, Int32 port, int x)
        {
            TcpClient client;

            sendData("Connecting to Host: " + server + " on port: " + port.ToString() + "...");
            sendStatus("Connecting", x);

            try
            {
                client = new TcpClient(server.ToString(), port); 

                if (false)
                {

                }               

                if (true)
                {
                    sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..ESTABLISHED");
                    sendStatus("Connected", x);        
                    receiveData(client, server, port);
                }

            }
            catch (Exception)
            {
                sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..FAILED");
                sendStatus("Failed", x);
            }
        }

        public void receiveData(TcpClient client, IPAddress server, int port)
        {
            Byte[] data = System.Text.Encoding.Default.GetBytes("|");
            data = new byte[1024];
            string stringData;
            bool connected;
            connected = true;

            while (connected == true)
            {
                string fromC = client.Client.RemoteEndPoint.ToString();
                NetworkStream ns = client.GetStream();
                int recv = ns.Read(data, 0, data.Length);
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                sendUpdate("{" + fromC + "}" + stringData);
                connected = IsConnected(client);
            }

            if (connected == false)
            {
                sendData("Connection to Host: " + server + " on port: " + port.ToString() + "..LOST");
                sendLost(server);
            }
        }

        public bool IsConnected(TcpClient client)
        {
            try
            {
                if (client != null && client.Client != null && client.Client.Connected)
                {
                    if (client.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] buff = new byte[1];
                        if (client.Client.Receive(buff, SocketFlags.Peek) == 0)
                        {
                            return false;
                        }
                        else
                        {
                            return true;
                        }
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }
    }       

这是对我有用的最终代码:

我的Class:

 public void tcpConnect(object pos)
        {
            IPAddress hostIP = IPAddress.Parse(pos.ToString().Split(':')[0]);
            int hostPort = Int32.Parse(pos.ToString().Split(':')[1]);
            rowInd = Int32.Parse(pos.ToString().Split(':')[2]);

            var client = new TcpClient();            

            if (!client.ConnectAsync(hostIP, hostPort).Wait(1000))
            {
                sendData("Connection to Host: " + hostIP + " on port: " + hostPort.ToString() + ".FAILED");
                sendStatus("Failed", "", rowInd);
                return;
            }

            if (true)
            {
                sendData("Connection to Host: " + hostIP.ToString() + " on port: " + hostPort.ToString() + "..ESTABLISHED");
                Thread thread = new Thread(new ParameterizedThreadStart(ClientHandler));
                thread.IsBackground = true;
                Thread.FreeNamedDataSlot(hostIP.ToString() + rowInd.ToString());
                thread.Name = hostIP.ToString() + rowInd.ToString();
                thread.Start(client);
                threadID = thread.ManagedThreadId.ToString();
                sendStatus("Connected", threadID, rowInd);
            }
        }

        public bool IsConnected(TcpClient client)
        {
            try
            {
                if (client != null && client.Client != null && client.Client.Connected)
                {
                    if (client.Client.Poll(0, SelectMode.SelectRead))
                    {
                        byte[] buff = new byte[1];
                        if (client.Client.Receive(buff, SocketFlags.Peek) == 0)
                        {
                            return false;
                        }
                        else
                        {
                            return true;
                        }
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

        public void ClientHandler(object c)
        {            
            TcpClient client = (TcpClient)c;            
            NetworkStream netstream = client.GetStream();
            string fromC = client.Client.RemoteEndPoint.ToString();
            string fromIP = fromC.Split(':')[0];

            bool connected = true;
            while (connected)
            {
                Thread.Sleep(10);
                try
                {
                    byte[] data = new byte[client.ReceiveBufferSize];
                    data = System.Text.Encoding.Default.GetBytes("|");
                    data = new byte[1024];
                    string stringData;                   
                    NetworkStream ns = client.GetStream();
                    int recv = ns.Read(data, 0, data.Length);
                    stringData = Encoding.ASCII.GetString(data, 0, recv);
                    sendUpdate("|" + fromC + "|" + stringData);
                    connected = IsConnected(client);
                }
                catch (Exception err)
                {   
                    connected = false;
                    sendLost(fromIP);

                    using (StreamWriter w = File.AppendText("Arch-PTO.log"))
                    {
                        Log("tcpServices.ClientHandler: " + err.Message, w);
                    }
                }
            }            
            sendLost(fromIP);
        }