Ошибка сокета TCP в C# - 10060

У меня есть служба Windows, выступающая в качестве сервера. И я запускаю одну форму окна приложения localhost в качестве клиента. Обе программы используют TCP-соединение для отправки / получения данных. Сервер прослушивает порт 8030. Программа работает нормально.

Но когда я улучшил клиентскую программу для связи через определенный порт, скажем, 9030. При подключении к серверу генерируется следующее исключение.

Попытка подключения не удалась, потому что подключенная сторона не ответила должным образом через определенный промежуток времени, или не удалось установить соединение, так как подключенный хост не ответил 192.168.10.198:8030

Любое предложение будет высоко оценено.

Спасибо, Мадхусмита

Для справки

Код программы сервера

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

Код клиентской программы

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.");
        }
    }
}

1 ответ

Решение

Примечание: вам не нужно привязывать локальный конец клиентского сокета - фреймворк и / или ОС будут связываться с эфемерным портом автоматически. Фактически, если вы привязываете сокет к 127.0.0.1, предполагая, что подключение не вызывает исключение о недоступных хостах, произойдет одно из двух (я не уверен, какой именно):

  • Клиент попытается подключиться к серверу, но, поскольку локальный конец привязан к IP-адресу интерфейса обратной связи, он будет отправлять его по сети, а не по сети. -или же-
  • Клиент правильно направит пакет через сетевую карту, и сервер получит его. Сервер отвечает "ОК, давайте настроим это соединение" клиенту... но, поскольку клиент сказал, что его адрес был 127.0.0.1, именно здесь сервер будет пытаться подключиться. Используя свой собственный петлевой интерфейс, потому что именно туда направляется 127.0.0.1.

В любом случае пакеты теряются в одном из интерфейсов обратной связи машины, и клиент никогда не увидит ответ.

Если вам необходимо подключиться к клиенту, выберите свой реальный IP-адрес или используйте IPAddress.Any, вот так:

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

Это будет привязано к данному порту, но все же позволит ОС выбирать IP-адрес. Но 127.0.0.1, вероятно, не будет работать.

Другие вопросы по тегам