简体   繁体   中英

C# TcpClient cannot connect

I create a class which connects with other computer in LAN. When I induce a method Connect first time all is ok, but after work class the variable lose a reference to this object.

But if I try do create this object again and I induce a method Connect I have an error which is saying "Only one using each socket adress(protocol / network address / port) is permitted"

this error is when I try to do

partner.Connect(partnerIPEndPoint); .

What is bad in my class? I would appreciate if anybody could help me. Thanks in advance.

Here is my class:

using System;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;


namespace AudioNetwork
{
    class ConnectToServer : IDisposable
    {
        public int BeepAmonut { get; set; }
        public int Speed { get; set; }
        public IPAddress MyIPAddress { get; set; }
        public IPAddress PartnerIPAddress { get; set; }
        private NetworkStream stream;
        private TcpClient partner;


        public void Connect()
        {
           IPEndPoint myIPEndPoint = new IPEndPoint(MyIPAddress, 800);
           IPEndPoint partnerIPEndPoint = new IPEndPoint(PartnerIPAddress, 800);
           partner = new TcpClient(myIPEndPoint);              

           partner.Connect(partnerIPEndPoint);
           stream = partner.GetStream();
           Messanger(stream);
        }

        protected virtual void Messanger(NetworkStream myStream)
        {
            byte[] data = { 2, 1 };

            myStream.Write(data, 0, data.Length);
            Play(2000);

        }

        public void Play(int time)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            while (sw.ElapsedMilliseconds <= 2100)
            {
                if (sw.ElapsedMilliseconds >= time)
                {
                    break;
                }
            }
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
            stream.Dispose();
            stream.Close();
            partner.Client.Dispose();
            partner.Close();
        }
    }

    class ConnectToClient : ConnectToServer
    {
        protected override void Messanger(NetworkStream myStream)
        {
            byte[] data = new byte[256];
            int bytes = myStream.Read(data, 0, data.Length);
            if (data[0] == 2)
            {
                Play(1980);
            }
        }
    }
}

You assign a hardcoded port to the local endpoint, and don't close it.

  • When you open the first connection, you have a local socket on port 800 connected to the remote socket at port 800.
  • You then forget to close this connection (as you never call Dispose on steam or partner - I don't see your Dispose function being called anywhere)
  • When you're trying to open the second connection on the local port 800, it is already taken by the fist connection, which leads to the error you're encountering.

The solution is to let the OS assign an automatic port number for the local socket. That way:

  • When you open the first connection, you have a local socket on an auto-assigned port number connected to the remote socket at port 800.
  • When you open the second connection, even if the first one isn't closed yet, the OS will assign a different port number to the second socket and connect it to the remote socket at port 800.

In code, that would be simply:

partner = new TcpClient(); 

And get rid of all that MyIPAddress stuff.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM