Search code examples
c#socketsudptcpclienttcpserver

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


Scenario:

I have multiple machines, each wit hit's own IP, that run a tcpServer, all on the same port. During each transaction data is sent if the tcpServer port is opened. It, looks for a client before opening the port.

What I Need:

I'm writing an app, that needs to: 1. Check through the list of IP's if they are availible 2. Open a tcpClient port to each machine IP, (all on the same ports) 3. After every specified time make sure the connection is open, if not reopen connection.

Future:

I use an XMl file to give the SQL data which is used to get the list of machines and the port to listen on. In this xml is a udp setting as well, if this is yes, then the data being sent, must be received and redirected to a specified UDP port.

The 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);
                }
            }
        }

The part of the code that repeats every few seconds:

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
        }

Solution

  • I got the following code toe work, from my class I can now make multiple connections, however. The part where I call another method to listen and receive the data blocks the first method and holds it untill the connection drops without making further connections.

    My 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;
                }
            }
        }