Pregunta

Tengo un servicio de Windows que actúa como servidor.Y ejecuto una aplicación de Windows Forme localhost como cliente.Ambos programas utilizan una conexión de socket TCP para enviar / recibir datos. El servidor escucha en el puerto 8030. El programa funciona bien.

PERO cuando mejoré el programa cliente para que se comunique en un puerto específico, digamos 9030. Mientras se conecta al servidor, genera la siguiente excepción.

Un intento de conexión falló porque la parte conectada no respondió correctamente después de un período de tiempo, o la conexión establecida falló porque el host conectado no respondió 192.168.10.198:8030

Cualquier sugerencia será muy apreciada.

Gracias, Madhusmita

Para referencia

Código de programa del servidor

public partial class TestService : ServiceBase
{
    Socket serverSocket = null;
    public Timer timer1;
    IPEndPoint ipEndPoint;

    public TestService()
    {
        InitializeComponent();
        timer1 = new Timer(10000);
        timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
    }

protected override void OnStart(string[] args)
    {
        EventLog.WriteEntry("Application", "Service started", EventLogEntryType.Information, 555);
        try
        {

            ipEndPoint = new IPEndPoint(IPAddress.Any, 8030);
            //Defines the kind of socket we want :TCP
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            //Bind the socket to the local end point(associate the socket to local end point)
            serverSocket.Bind(ipEndPoint);
            //listen for incoming connection attempt
            // Start listening, only allow 10 connection to queue at the same time
            serverSocket.Listen(10);
            timer1.Start();
        }
        catch (SocketException ex)
        {
            EventLog.WriteEntry("Application",  ex.ErrorCode + "-" +ex.Message, EventLogEntryType.Error, 555);
        }
        catch (Exception ex)
        {
            EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
        }
    }

    void timer1_Elapsed(object sender, ElapsedEventArgs e)
    {
        try
        {

            // The program is suspended while waiting for an incoming connection.
            // This is a synchronous TCP application
            Socket handler = serverSocket.Accept();              
            byte[] fileDetails = new byte[1500];

            //Recieve the file details
            handler.Receive(fileDetails);              
            int fileNameLength = BitConverter.ToInt32(fileDetails, 0);
            string fileName = Encoding.ASCII.GetString(fileDetails, 4, fileNameLength);
            int fileLength = BitConverter.ToInt32(fileDetails, 4 + fileNameLength);  

            FileStream fs = new FileStream(@"C:\Demo\" + fileName, FileMode.Append, FileAccess.Write);
            int byteRead = 0;

            while (byteRead < fileLength)
            {
                byte[] data = new Byte[1500];
                //Recieve teh data and write to the file
                int r = handler.Receive(data);
                fs.Write(data, 0, r);
                byteRead += r;
            }

            fs.Close();

            EventLog.WriteEntry("Application", "File saved successfully", EventLogEntryType.SuccessAudit, 555);               
            EndPoint endPoint = (EndPoint)ipEndPoint;
            handler.Send(Encoding.ASCII.GetBytes("Done"));
            handler.Close();
        }
        catch (SocketException ex)
        {
            EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
        }
        catch (IOException ex)
        {
            EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);
        }
        catch (Exception ex)
        {
            EventLog.WriteEntry("Application", ex.Message, EventLogEntryType.Error, 555);

        }
    }


    protected override void OnStop()
    {
        timer1.Stop();
    }

    protected override void OnPause()
    {
        timer1.Stop();
    }

    protected override void OnContinue()
    {
        timer1.Start();

    }
    protected override void OnShutdown()
    {
        timer1.Stop();
    }
}

Código de programa del cliente

public partial class Form1 : Form
{
    Socket socketClient;
    IPEndPoint remoteEndPoint;
    public Form1()
    {
        InitializeComponent();

    }

    private void buttonX1_Click(object sender, EventArgs e)
    {
        try
        {
            //Code to connect to server by by specifing the IP and port of the server on 
            //which the server application is hosted
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //socketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,(int)1);

            //IP address of the machine where the server program is hosted
            IPAddress remoteIPAddress = IPAddress.Parse(txtXIPAddress.Text.Trim());

            //Specify the specific port no thart the server listens to accept the data
            int port = int.Parse(txtXPort.Text.Trim());
            remoteEndPoint = new IPEndPoint(remoteIPAddress, port);

            **//This two line causing the exception**
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9030);
            socketClient.Bind(endPoint);

            //Establish the connection to server
            socketClient.Connect(remoteEndPoint);

            MessageBox.Show("Connection established. Please select a  file to send.");
        }
        catch (SocketException ex)
        {
            MessageBox.Show(ex.ErrorCode.ToString() + "-" + ex.Message);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void btnXBrowse_Click(object sender, EventArgs e)
    {
        if (socketClient != null)
        {
            openFileDialog1.ShowDialog();
        }
        else
        {
            MessageBox.Show("Please connect to the server first");
        }

    }

    private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
    {

        txtXFile.Text = openFileDialog1.FileName;
    }

    private void btnXTransfer_Click(object sender, EventArgs e)
    {
        //Check if the socket is connected to the remote host 
        //otherwise prompt user to get connected to the server first
        if (socketClient != null && socketClient.Connected)
        {
            //If any file is selected then only proceed with transfer
            if (!openFileDialog1.FileName.Equals(string.Empty))
            {
                FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
                try
                {
                    //Get the filename
                    string filename = Path.GetFileName(openFileDialog1.FileName);

                    //Covert the file name in form of byte
                    byte[] fileNameByte = Encoding.ASCII.GetBytes(filename);

                    //4- to store the filename length(as int - 4bytes)
                    //8- to stote the file content length(as long take 8 bytes)
                    int totalLength = 4 + fileNameByte.Length + 8;

                    //Clientdata[] reprents the data to sent to the server 
                    //which represent the file details
                    byte[] clientData = new byte[totalLength];
                    byte[] fileNameLength = BitConverter.GetBytes(fileNameByte.Length);
                    byte[] fileContentLength = BitConverter.GetBytes(fs.Length);

                    //Copy all the data ClientData array
                    fileNameLength.CopyTo(clientData, 0);
                    fileNameByte.CopyTo(clientData, 4);
                    fileContentLength.CopyTo(clientData, 4 + fileNameByte.Length);

                    //Send the data to server
                    socketClient.Send(clientData);

                    int byteRead = 0;
                    int bytesToRead = (int)fs.Length;

                    while (bytesToRead > 0)
                    {
                        byte[] data = new Byte[1500];
                        byteRead = bytesToRead > 1500 ? 1500 : bytesToRead;
                        int n = fs.Read(data, 0, byteRead);

                        //Send the data to server
                        socketClient.Send(data);
                        bytesToRead -= n;
                    }

                    //Code block to get the success message from server
                    byte[] successmessage = new byte[4];
                    int msg = socketClient.Receive(successmessage);

                    if (Encoding.ASCII.GetString(successmessage).Equals("Done"))
                    {
                        MessageBox.Show("transfered the file successfully");
                        txtXFile.Text = string.Empty;
                        openFileDialog1.FileName = string.Empty;
                    }

                }

                catch (SocketException ex)
                {
                    MessageBox.Show(ex.ErrorCode + "-" + ex.Message);
                }
                catch (IOException ex)
                {
                    MessageBox.Show(ex.Message);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    fs.Close();
                    if (socketClient != null && socketClient.Connected)
                    {
                        socketClient.Shutdown(SocketShutdown.Both);
                        socketClient.Close(); ;
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select afile to transfer.");
            }
        }
        else
        {
            MessageBox.Show("Please connect to the host.");
        }
    }
}
¿Fue útil?

Solución

Nota: No es necesario vincular el extremo local del socket del cliente; el marco y / o el sistema operativo se vincularán a un puerto efímero automáticamente. De hecho, si vincula el socket a 127.0.0.1, asumiendo que la conexión no genera una excepción sobre hosts inalcanzables, sucederá una de dos cosas (no estoy seguro de cuál):

  • El cliente intentará conectarse al servidor, pero dado que el extremo local está vinculado a la IP de la interfaz de bucle invertido, lo enviará en lugar de hacerlo a través de la red. -o-
  • El cliente enrutará correctamente el paquete a través de la NIC y el servidor lo obtendrá. El servidor responde "OK, configuremos esta conexión" al cliente ... pero como el cliente dijo que su dirección era 127.0.0.1, ahí es donde el servidor intentará conectarse. Usando su propia interfaz de loopback, porque ahí es donde se enruta 127.0.0.1.

De cualquier manera, los paquetes se pierden en una de las interfaces de loopback de las máquinas y el cliente nunca verá una respuesta.

Si debe vincular el cliente, elija su dirección IP real o use IPAddress.Any, así:

var endPoint = new IPEndPoint(IPAddress.Any, 9030);

Eso se vinculará a un puerto determinado, pero aún permitirá que el sistema operativo elija la dirección IP. Pero 127.0.0.1 probablemente no funcionará.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top