无法与TcpListener建立连接

时间:2012-01-14 12:28:35

标签: c# sockets tcplistener

在过去的两周里,我一直试图解决问题,但显然没有成功。 我有一个使用TcpListener类的服务器和一个使用TcpClient类的客户端。

我的测试是在我的内部家庭网络(1级路由器)中使用2台计算机。 试图连接,客户端计算机得到"连接请求超时"异常。

我已经尝试过的事情:

  1. 在同一台计算机上运行客户端和服务器 - 工作
  2. 收听0.0.0.0端口6666(使用netstat检查以确保服务器正在侦听)
  3. 禁用客户端和服务器防火墙
  4. 尝试使用telnet连接我的远程应用程序(拒绝"客户端代码错误"可能性)
  5. 在两台计算机上安装telnet,并成功连接
  6. 仍然我的服务器似乎没有任何连接。客户端计算机是Windows XP,服务器计算机是Windows 7。

    请帮助,我真的坚持这个。

    编辑 - 服务器代码 - >

    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    
    namespace Utils
    {
        public class ClientConnection
    {
        public ClientConnection(IPHostEntry hostName, TcpClient client)
        {
            HostName = hostName;
            Client = client;
        }
    
        public IPHostEntry HostName { get; set; }
    
        public TcpClient Client { get; set; }
    }
    
    public class SocketServer : IDisposable
    {
    
        private const int DefaultRecieveSize = 1024;
        protected const int ReceiveTimeoutBeforeQuiting = 5000;
    
        private readonly Encoding _defaultEncoding = Encoding.ASCII;
        private readonly TcpListener _socket;
    
        protected Dictionary<IPAddress, ClientConnection> Clients;
        private static object _locker;
    
        private readonly AutoResetEvent _listeningStopEvent;
        private readonly Thread _listeningThread;
    
        private readonly AutoResetEvent _acceptNewClientEvent;
    
        public delegate void ClientsListChangedEvent();
        public event ClientsListChangedEvent ClientsChangedEvent;
    
        private Timer _refreshClientsTimer;
        private static int _updateClientListInterval;
    
        #region Ctors
    
        protected SocketServer(int port)
        {
            _socket = new TcpListener(IPAddress.Parse("0.0.0.0"),port);
            Clients = new Dictionary<IPAddress, ClientConnection>();
    
            _updateClientListInterval = Convert.ToInt32(ConfigurationManager.AppSettings["UpdateClientListInterval"]);
    
    
            _listeningThread = new Thread(AcceptNewConnections);
            _listeningStopEvent = new AutoResetEvent(false);
    
            _acceptNewClientEvent = new AutoResetEvent(false);
            _locker = new object();
    
            _socket.Start();
        }
    
        #endregion
    
        #region Send methods
    
        protected void SendString(IPAddress client, string data)
        {
            // implementation here
        }
    
        #endregion
    
        #region Receieve methods
    
        protected MemoryStream GetInputDataAsMemoryStream(IPAddress client)
        {
            // implementation here    
        }
    
        protected string GetInputDataAsMemoryString(IPAddress client)
        {
            // implementation here    
        }
    
        protected string GetInputDataAsMemoryString(IPAddress client, int timeout)
        {
            // implementation here    
        }  
    
        #endregion
    
        #region Listening methons
    
        public void StopListening()
        {
            _listeningStopEvent.Set();
    
            // todo : check if works
            _refreshClientsTimer.Dispose();
        }
    
        public bool StartListening()
        {
            if (_listeningThread.ThreadState == ThreadState.Unstarted)
            {
                _listeningThread.Start();
    
                // start refreshing clients list too. update clients list every 10 seconds
                _refreshClientsTimer = new Timer(UpdateList, null, 0, _updateClientListInterval * 1000);
                return true;
            }
            return false;
        }
    
        private void AddClientCallback(IAsyncResult ar)
        {
            // get all needed data before entering lock 
            if (_socket != null)
            {
                TcpClient client;
                try
                {
                    client = _socket.EndAcceptTcpClient(ar);
                }
                catch (ObjectDisposedException)
                {
                    // probebly server has been closed. exit
                    return;
                }
    
                var clientEndPoint = client.Client.RemoteEndPoint;
                var ip = SocketFunctions.ExtractIpFromEndPoint(clientEndPoint);
                IPHostEntry hostName;
                try
                {
                    hostName = SocketFunctions.ExtractHostnameFromEndPoint(clientEndPoint);
                }
                catch(SocketException)
                {
                    // error while parsing from ip to host name. Put default
                    hostName = new IPHostEntry();
                }
    
    
                // check if given ip already connected
                if (!Clients.ContainsKey(ip))
                {
                    lock (_locker)
                    {
                        Clients.Add(ip, new ClientConnection(hostName, client));
                    }
    
                    // notify that a new clients has been added
                    ClientsChangedEvent.Invoke();
                }
            }
            // a new client has accepted
            _acceptNewClientEvent.Set();
        }
    
        private void AcceptNewConnections(object obj)
        {
            var shouldStop = false;
    
            while (!shouldStop)
            {
                _socket.BeginAcceptTcpClient(AddClientCallback, null);
    
                AutoResetEvent[] events = { _listeningStopEvent, _acceptNewClientEvent };
                var result = WaitHandle.WaitAny(events);
    
                if (result == 0)
                {
                    shouldStop = true;
                }
            }
        }
    
        #endregion 
    
        public List<KeyValuePair<string, string>> GetConnectedClients()
        {
            var connectedClients = new List<KeyValuePair<string, string>>();
    
            lock (_locker)
            {
                foreach (var client in Clients)
                {
                    // get only connected clients. Don`t remove - next Timer round will do it anyway and I don`t want to lock _clients
                    if (client.Value.Client.Connected)
                    {
                        connectedClients.Add(new KeyValuePair<string, string>(client.Key.ToString(), client.Value.HostName.HostName));
                    }
                }
            }
    
            return connectedClients;
        }
    
        private static void CheckConnectionStatus(TcpClient client)
        {
            if (client.Client.Poll(0, SelectMode.SelectRead))
            {
                var checkConn = new byte[1];
                checkConn[0] = 0;
                try
                {
                    if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
                    {
                        throw new IOException();
                    }
                }
                catch (SocketException)
                {
                    // for me, both exceptions mean that there was a conncetion error. Throw IOException for this case too
                    throw new IOException();
                }
            }
        }
    
        public void UpdateList(object obj)
        {
            // iterate each client and check its state. Remove if not connected
            var tempClients = new Dictionary<IPAddress, ClientConnection>(Clients);
            var changedOccurred = false;
    
            lock (_locker)
            {
                foreach (var client in Clients)
                {
                    try
                    {
                        CheckConnectionStatus(client.Value.Client);
                    }
                    catch (IOException)
                    {
                        // client is not connected anymore
                        tempClients.Remove(client.Key);
                        changedOccurred = true;
                    }
    
                }
            }
    
            if (changedOccurred)
            {
                lock (_locker)
                {
                    Clients = tempClients;
                }
    
                // notify that a new clients has been added
                ClientsChangedEvent.Invoke();
            }
    
        }
    
        #region IDisposble
    
        public void Dispose()
        {
            if (_socket != null)
            {
                StopListening();
                _socket.Stop();
            }
        }
    
        #endregion
    
    }
    

    }

0 个答案:

没有答案