Невозможно подключиться к другим экземплярам той же программы через TCP - PullRequest
3 голосов
/ 01 февраля 2012

Я знаю, что это можно было спросить тысячу раз раньше, но я не могу найти какую-либо конкретную информацию о моем случае.

У меня есть клиентская программа на C #, которая должна подключаться к другим экземплярам клиента по локальной сети. Чтобы подключить одного клиента к другому, я использую подход TcpListener / TcpClient. Оба экземпляра имеют прослушиватель и могут создавать нового клиента для подключения / прослушивания друг друга (независимо от того, какой экземпляр начал подключение).

Для создания слушателя я использую следующий бит кода:

// In the constructor:
listener = new TcpListener(IPAddress.Any, 32842);
listenThread = new Thread((ThreadStart)ListenForConnections);
listenThread.Name = "ListenThread";
listenThread.IsBackground = true;
listenThread.Start();

// Listening for connections:
private void ListenForConnections()
{
    listener.Start();
    Console.WriteLine("Started listening for connections");
    for (; ; )
    {
        if (listener.Pending())
        {
            using (TcpClient client = listener.AcceptTcpClient())
            {
                // My own layer over the TcpClient.
                AsyncTCPClient other = new AsyncTCPClient(client);
                Console.WriteLine("Connection from " + client.Client.RemoteEndPoint);
                other.Received += DataReceived;
                other.Exception += ExceptionOccurred;
                connections.Add("Player", other);
                other.Start();
            }
        }
        else
        {
            Thread.Sleep(5);
        }
    }
}

Чтобы создать и подключиться к другому клиенту, я использую следующий бит кода:

public void Connect(IPEndPoint other)
{
    if (socket == null)
    {
        socket = new TcpClient(AddressFamily.InterNetwork);
        socket.Client.ReceiveBufferSize = 2 * 1024 * 1024;
    }
    // Should force-close the socket after 5 seconds if it can't be closed automatically.
    socket.LingerState = new LingerOption(true, 5);
    socket.BeginConnect(other.Address, other.Port, ConnectionCallback, other);
    IsConnecting = true;
}

ConnectionCallback, заданный в качестве параметра для BeginConnect, выглядит следующим образом:

private void ConnectionCallback(IAsyncResult result)
{
    IsConnecting = false;
    IsConnected = socket.Connected;
    if (IsConnected)
    {
        IPEndPoint connectedTo = (IPEndPoint)result.AsyncState;
        stream = socket.GetStream();
        if (Connected != null)
        {
            Connected(this, null);
        }
    }
    else
    {
        if (Exception != null)
        {
            RaiseException(new Exception("Unable to connect to host"));
        }
    }
}

Однако каждый раз, когда я получаю обратный вызов, TcpClient не может подключиться к другому экземпляру, и генерируется событие Exception. Теперь при поиске в Интернете (Google) я обнаружил, что он может иметь отношение к брандмауэру по обе стороны соединения. Но я проверил это со всеми выключенными брандмауэрами, так что этого не может быть.

1 Ответ

2 голосов
/ 01 февраля 2012

Я не вижу, чтобы Socket.EndConnect () вызывался в обратном вызове.Смотрите это в MSDN: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.endconnect.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...