public static async Task <TcpMultiPartyNetworkSession> EstablishAsync(Party localParty, IPAddress address, int startPort, int numberOfParties) { TcpTwoPartyNetworkSession[] remotePartySessions = new TcpTwoPartyNetworkSession[numberOfParties - 1]; for (int i = 0; i < localParty.Id; ++i) { remotePartySessions[i] = await TcpTwoPartyNetworkSession.ConnectAsync(localParty, address, startPort + i); } TcpListener listener = new TcpListener(IPAddress.Any, startPort + localParty.Id) { ExclusiveAddressUse = true }; listener.Start(); for (int j = localParty.Id + 1; j < numberOfParties; ++j) { remotePartySessions[j - 1] = await TcpTwoPartyNetworkSession.AcceptAsync(localParty, listener); } listener.Stop(); for (int i = 0; i < numberOfParties; ++i) { if (i != localParty.Id && !remotePartySessions.Any(session => session.RemoteParty.Id == i)) { throw new NetworkConsistencyException("Inconsistent TCP connection graph."); } } return(new TcpMultiPartyNetworkSession(localParty, remotePartySessions)); }
public static async Task <TcpMultiPartyNetworkSession> EstablishAsync(Party localParty, IPEndPoint[] endPoints) { if (localParty.Id < 0 || localParty.Id >= endPoints.Length) { throw new ArgumentException($"Local party id {localParty.Id} is out of range."); } IPEndPoint localEndPoint = endPoints[localParty.Id]; TcpTwoPartyNetworkSession[] outgoingSessions = await TcpTwoPartyNetworkSession.ConnectAsync( localParty, endPoints, localParty.Id ); TcpTwoPartyNetworkSession[] incomingSessions = await TcpTwoPartyNetworkSession.AcceptAsync( localParty, localEndPoint, endPoints.Length - localParty.Id - 1 ); List <ITwoPartyNetworkSession> remotePartySessions = new List <ITwoPartyNetworkSession>(endPoints.Length - 1); remotePartySessions.AddRange(outgoingSessions); remotePartySessions.AddRange(incomingSessions); for (int i = 0; i < endPoints.Length; ++i) { if (i != localParty.Id && remotePartySessions.All(session => session.RemoteParty.Id != i)) { throw new NetworkConsistencyException("Inconsistent TCP connection graph."); } } return(new TcpMultiPartyNetworkSession(localParty, remotePartySessions)); }