Exemplo n.º 1
0
        private void AcceptClient(IAsyncResult ar)
        {
            TcpClient newClient;

            try
            {
                // a new connection has been accepted
                newClient = _listener.EndAcceptTcpClient(ar);
                Debug.WriteLine("Listener established TCP connection with " + ((IPEndPoint)newClient.Client.RemoteEndPoint).Address.ToString());
            }
            catch (ObjectDisposedException)
            {
                // occurs if we close the TCP listener while waiting for data
                return;
            }
            catch (IOException ex)
            {
                Debug.WriteLine("Caught [" + ex.GetType().ToString() + "]\n\n" + ex.StackTrace);
                return;
            }
            catch (SocketException ex)
            {
                Debug.WriteLine("Caught [" + ex.GetType().ToString() + "]\n\n" + ex.StackTrace);
                return;
            }

            // keep listening for more connections
            _listenerAsyncResult = _listener.BeginAcceptTcpClient(AcceptClient, new object());


            NetworkStream     ns   = newClient.GetStream();
            IPAddress         addr = ((IPEndPoint)newClient.Client.RemoteEndPoint).Address;
            TcpPeerConnection conn = new TcpPeerConnection(newClient, ns, addr);

            // add connection to the peer list
            if (_peerConns.ContainsKey(addr))
            {
                try
                {
                    _peerConns[addr].stream.Close();
                    _peerConns[addr].client.Close();
                }
                catch (Exception e)
                {
                    // eat exception - exceptions likely when closing a dead connection that's been reopened
                    Debug.WriteLine("Exception while closing connection assumed to be dead");
                    Debug.WriteLine(e);
                }
                _peerConns[addr] = conn;
            }
            else
            {
                _peerConns.Add(addr, conn);
            }

            // asynchronously read data from the connection. When data arrives, ReceiveData() will be called
            // todo this can throw an exception
            ns.BeginRead(conn.buffer, 0, conn.buffer.Length, ReceiveData, conn);
        }
Exemplo n.º 2
0
        private void ConnectedToPeer(IAsyncResult ar)
        {
            TcpPeerConnection conn = (TcpPeerConnection)ar.AsyncState;
            IPAddress         addr = conn.remoteAddress;

            // check if connection was successful
            if (!conn.client.Connected)
            {
                Debug.WriteLine("Failed to connect to " + addr.ToString());
                return;
            }

            conn.stream = conn.client.GetStream();

            // see if we already have a connection to this peer -- if so, close it
            if (_peerConns.ContainsKey(addr))
            {
                TcpPeerConnection oldConn = _peerConns[addr];
                try
                {
                    oldConn.stream.Close();
                    oldConn.client.Close();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Caught " + ex.ToString() + " while closing old connection");
                }
                finally
                {
                    _peerConns.Remove(addr);
                }
            }

            // store the peer in our peers list
            _peerConns.Add(addr, conn);


            Debug.WriteLine("Established connection to " + addr.ToString());

            // see if the peer has any data to send us
            conn.stream.BeginRead(conn.buffer, 0, conn.buffer.Length, ReceiveData, conn);

            // send any queued messages to the peer
            Queue <Message> q        = _sendQueue[addr];
            Message         sendThis = q.Dequeue();

            if (sendThis != null)
            {
                SendMessage(sendThis, addr);
            }
        }
Exemplo n.º 3
0
        private void DataSent(IAsyncResult ar)
        {
            TcpPeerConnection conn = (TcpPeerConnection)ar.AsyncState;

            try
            {
                conn.stream.EndWrite(ar);
            }
            catch (SocketException ex)
            {
                Debug.Write("Caught SocketException in DataSent");
                Debug.Write(ex);
                try
                {
                    conn.stream.Close();
                    conn.client.Close();
                }
                catch (Exception)
                {
                    // have to eat it
                }
            }
            catch (IOException ex)
            {
                Debug.Write("Caught IOException in DataSent");
                Debug.Write(ex);
                try
                {
                    conn.stream.Close();
                    conn.client.Close();
                }
                catch (Exception)
                {
                    // have to eat it
                }
            }
            catch (ObjectDisposedException ex)
            {
                // occurs if we close the TCP connection while trying to send data
                Debug.Write("Caught ObjectDisposedException in DataSent");
                Debug.Write(ex);
                return;
            }
        }
Exemplo n.º 4
0
        public void SendMessage(Message msg, IPAddress addr)
        {
            // see if we have an existing connection to this peer
            TcpPeerConnection conn;

            if (_peerConns.ContainsKey(addr))
            {
                // convert message to bytes and send it
                conn = _peerConns[addr];
                try
                {
                    byte[] msgBytes = Encoding.ASCII.GetBytes(msg.Serialize());
                    conn.stream.BeginWrite(msgBytes, 0, msgBytes.Length, DataSent, conn);
                    return;
                }
                catch (SocketException ex)
                {
                    Debug.Write("Caught SocketException in SendMessage");
                    Debug.Write(ex);
                    try
                    {
                        conn.stream.Close();
                        conn.client.Close();
                    }
                    catch (Exception)
                    {
                        // have to eat it
                    }

                    // fall through queue the message instead
                }
                catch (IOException ex)
                {
                    Debug.Write("Caught IOException in SendMessage");
                    Debug.Write(ex);
                    try
                    {
                        conn.stream.Close();
                        conn.client.Close();
                    }
                    catch (Exception)
                    {
                        // have to eat it
                    }

                    // fall through queue the message instead
                }
                catch (ObjectDisposedException ex)
                {
                    // occurs if we close the TCP connection while trying to send data
                    Debug.Write("Caught ObjectDisposedException in SendMessage");
                    Debug.Write(ex);
                    return;
                }
            }

            // either we didn't have an active connection, or we tried to send on our active connection and failed,
            // so add the message to the queue
            if (!_sendQueue.ContainsKey(addr))
            {
                _sendQueue.Add(addr, new Queue <Message>());
            }
            _sendQueue[addr].Enqueue(msg);

            // connect to the peer
            conn = new TcpPeerConnection(null, null, addr);
            TcpClient client = new TcpClient();

            conn.client = client;
            client.BeginConnect(addr, Port, ConnectedToPeer, conn);

            // ConnectedToPeer() will send the message once we're connected
        }