Ошибка сокета TCP в C # - 10060 - PullRequest
0 голосов
/ 20 октября 2011

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

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

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

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

Спасибо, Madhusmita

Для справки

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

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 Ответ

2 голосов
/ 20 октября 2011

Примечание: вам не нужно привязывать локальный конец клиентского сокета - фреймворк и / или ОС будут связываться с эфемерным портом автоматически.На самом деле, если вы привязываете сокет к 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, вероятно, не будет работать.

...