/// <summary> /// Attempts to connect to another server application from this server core/application. /// </summary> /// <param name="endPoint"></param> /// <param name="applicationName"></param> /// <param name="hailMessage"></param> /// <param name="callbackObject">Object that will be returned in the response. (Not sent to the server)</param> /// <returns>Indicates whether a connection has been successfully attempted (doesn't indicate if it was established).</returns> public bool ConnectToServer(IPEndPoint endPoint, string hailMessage, object callbackObject = null) { if (endPoint == null) { return(false); } else { var msg = lidgrenServerObj.CreateMessage(); msg.Write(hailMessage); msg.Write(ServerTypeUniqueByte); #if DEBUGBUILD this.ClassLogger.LogDebug("Attempting to connect to another server."); #endif NetConnection possibleConnection = lidgrenServerObj.Connect(endPoint, msg); ConnectionResponse response = new ConnectionResponse(endPoint, possibleConnection, hailMessage, callbackObject); this.UnhandledServerConnections.Add(response); return(true); } }
private void MGServer_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; NetPeerConfiguration config = new NetPeerConfiguration(applicationIdentifier); config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest); config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse); config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess); if (availableSession == null) { config.Port = port; } // create and start server peer = new NetServer(config); peer.Start(); myLocalAddress = GetMyLocalIpAddress(); IPAddress adr = IPAddress.Parse(myLocalAddress); myLocalEndPoint = new IPEndPoint(adr, port); // force a little wait until we have a LocalGamer otherwise things // break. This is the first item in the queue so it shouldnt take long before we // can continue. while (session.LocalGamers.Count <= 0) { Thread.Sleep(10); } if (availableSession != null) { if (!this.online) { peer.Connect(availableSession.EndPoint); } else { RequestNATIntroduction(availableSession.EndPoint, peer); } } else { if (this.online) { IPAddress ipaddr = NetUtility.Resolve(masterServer); if (ipaddr != null) { m_masterServer = new IPEndPoint(ipaddr, masterserverport); LocalNetworkGamer localMe = session.LocalGamers [0]; NetOutgoingMessage om = peer.CreateMessage(); om.Write((byte)0); om.Write(session.AllGamers.Count); om.Write(localMe.Gamertag); om.Write(session.PrivateGamerSlots); om.Write(session.MaxGamers); om.Write(localMe.IsHost); om.Write(myLocalEndPoint); om.Write(peer.Configuration.AppIdentifier); // send up session properties int[] propertyData = new int[session.SessionProperties.Count * 2]; NetworkSessionProperties.WriteProperties(session.SessionProperties, propertyData); for (int x = 0; x < propertyData.Length; x++) { om.Write(propertyData [x]); } peer.SendUnconnectedMessage(om, m_masterServer); // send message to peer } else { throw new Exception("Could not resolve live host"); } } } // run until we are done do { NetIncomingMessage msg; while ((msg = peer.ReadMessage()) != null) { switch (msg.MessageType) { case NetIncomingMessageType.UnconnectedData: break; case NetIncomingMessageType.NatIntroductionSuccess: #if !WINDOWS_PHONE Game.Instance.Log("NAT punch through OK " + msg.SenderEndPoint); #endif peer.Connect(msg.SenderEndPoint); break; case NetIncomingMessageType.DiscoveryRequest: // // Server received a discovery request from a client; send a discovery response (with no extra data attached) // // Get the primary local gamer LocalNetworkGamer localMe = session.LocalGamers [0]; NetOutgoingMessage om = peer.CreateMessage(); om.Write(session.RemoteGamers.Count); om.Write(localMe.Gamertag); om.Write(session.PrivateGamerSlots); om.Write(session.MaxGamers); om.Write(localMe.IsHost); int[] propertyData = new int[session.SessionProperties.Count * 2]; NetworkSessionProperties.WriteProperties(session.SessionProperties, propertyData); for (int x = 0; x < propertyData.Length; x++) { om.Write(propertyData [x]); } peer.SendDiscoveryResponse(om, msg.SenderEndPoint); break; case NetIncomingMessageType.VerboseDebugMessage: case NetIncomingMessageType.DebugMessage: case NetIncomingMessageType.WarningMessage: case NetIncomingMessageType.ErrorMessage: // // Just print diagnostic messages to console // #if !WINDOWS_PHONE Game.Instance.Log(msg.ReadString()); #endif break; case NetIncomingMessageType.StatusChanged: NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte(); if (status == NetConnectionStatus.Disconnected) { #if !WINDOWS_PHONE Game.Instance.Log(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " disconnected! from " + msg.SenderEndPoint); #endif CommandGamerLeft cgj = new CommandGamerLeft(msg.SenderConnection.RemoteUniqueIdentifier); CommandEvent cmde = new CommandEvent(cgj); session.commandQueue.Enqueue(cmde); } if (status == NetConnectionStatus.Connected) { // // A new player just connected! // if (!pendingGamers.ContainsKey(msg.SenderConnection.RemoteUniqueIdentifier)) { #if !WINDOWS_PHONE Game.Instance.Log(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " connected! from " + msg.SenderEndPoint); #endif pendingGamers.Add(msg.SenderConnection.RemoteUniqueIdentifier, msg.SenderConnection); SendProfileRequest(msg.SenderConnection); } else { #if !WINDOWS_PHONE Game.Instance.Log("Already have a connection for that user, this is probably due to both NAT intro requests working"); #endif } } break; case NetIncomingMessageType.Data: NetworkMessageType mt = (NetworkMessageType)msg.ReadByte(); switch (mt) { case NetworkMessageType.Data: byte[] data = new byte[msg.LengthBytes - 1]; msg.ReadBytes(data, 0, data.Length); CommandEvent cme = new CommandEvent(new CommandReceiveData(msg.SenderConnection.RemoteUniqueIdentifier, data)); session.commandQueue.Enqueue(cme); break; case NetworkMessageType.Introduction: var introductionAddress = msg.ReadString(); try { IPEndPoint endPoint = ParseIPEndPoint(introductionAddress); if (myLocalEndPoint.ToString() != endPoint.ToString() && !AlreadyConnected(endPoint)) { #if !WINDOWS_PHONE Game.Instance.Log("Received Introduction for: " + introductionAddress + " and I am: " + myLocalEndPoint + " from: " + msg.SenderEndPoint); #endif peer.Connect(endPoint); } } catch (Exception exc) { #if !WINDOWS_PHONE Game.Instance.Log("Error parsing Introduction: " + introductionAddress + " : " + exc.Message); #endif } break; case NetworkMessageType.GamerProfile: #if !WINDOWS_PHONE Game.Instance.Log("Profile recieved from: " + NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier)); #endif if (pendingGamers.ContainsKey(msg.SenderConnection.RemoteUniqueIdentifier)) { pendingGamers.Remove(msg.SenderConnection.RemoteUniqueIdentifier); msg.ReadInt32(); string gamerTag = msg.ReadString(); msg.ReadInt32(); msg.ReadInt32(); GamerStates state = (GamerStates)msg.ReadInt32(); state &= ~GamerStates.Local; CommandGamerJoined cgj = new CommandGamerJoined(msg.SenderConnection.RemoteUniqueIdentifier); cgj.GamerTag = gamerTag; cgj.State = state; CommandEvent cmde = new CommandEvent(cgj); session.commandQueue.Enqueue(cmde); } else { #if !WINDOWS_PHONE Game.Instance.Log("We received a profile for an existing gamer. Need to update it."); #endif } break; case NetworkMessageType.RequestGamerProfile: #if !WINDOWS_PHONE Game.Instance.Log("Profile Request recieved from: " + msg.SenderEndPoint); #endif SendProfile(msg.SenderConnection); break; case NetworkMessageType.GamerStateChange: GamerStates gamerstate = (GamerStates)msg.ReadInt32(); gamerstate &= ~GamerStates.Local; #if !WINDOWS_PHONE Game.Instance.Log("State Change from: " + msg.SenderEndPoint + " new State: " + gamerstate); #endif foreach (var gamer in session.RemoteGamers) { if (gamer.RemoteUniqueIdentifier == msg.SenderConnection.RemoteUniqueIdentifier) { gamer.State = gamerstate; } } break; case NetworkMessageType.SessionStateChange: NetworkSessionState sessionState = (NetworkSessionState)msg.ReadInt32(); foreach (var gamer in session.RemoteGamers) { if (gamer.RemoteUniqueIdentifier == msg.SenderConnection.RemoteUniqueIdentifier) { #if !WINDOWS_PHONE Game.Instance.Log("Session State change from: " + NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " session is now: " + sessionState); #endif if (gamer.IsHost && sessionState == NetworkSessionState.Playing) { session.StartGame(); } } } break; } break; } } // sleep to allow other processes to run smoothly // This may need to be changed depending on network throughput Thread.Sleep(1); if (worker.CancellationPending) { #if !WINDOWS_PHONE Game.Instance.Log("worker CancellationPending"); #endif e.Cancel = true; done = true; } } while (!done); }
public static void Main(string[] args) { try { using (var server = new NetServer()) { server.Listen((self) => { System.Console.WriteLine("Server is listening on: " + self.Address.ToString()); }); server.Connect((channel) => { System.Console.WriteLine("Client connected."); channel.Fault((c, exception) => { System.Console.WriteLine(((MiniNet.Exceptions.SocketException)exception).StatusCode.ToString()); System.Console.WriteLine(exception.ToString()); }); var encoding = Encoding.Unicode; var decoder = new StringDecoder(encoding); var encoder = new StringEncoder(encoding); //channel.Authenticate(); channel.Start(); channel.Message((self, buffer) => { if (buffer.Size > 0) { var str = decoder.Process(buffer); System.Console.WriteLine(str + "-" + buffer.Size + "-"); System.Console.WriteLine(buffer.DumpHex(int.MaxValue)); } }); /*var payload = "Server: Hello Client"; * var message = MiniNet.Buffers.Buffer.Create(encoding.GetByteCount(payload)); * * encoder.Process(message, payload); * channel.SendAsync(message);*/ Thread.Sleep(1000); //channel.Close(); }); server.Fault((exception) => { System.Console.WriteLine(exception.ToString()); }); server.Bind(8080, "localhost"); using (var client = new TcpClient()) { client.NoDelay = true; client.Connect(server.Address.Host, server.Address.Port); Thread.Sleep(100); var encoding = new UnicodeEncoding(false, false, true); var stream = client.GetStream(); //var reader = new StreamReader(stream, encoding); var writer = new StreamWriter(stream, encoding) { AutoFlush = true }; for (int i = 1; i <= 4; i++) { /*var bytesReceived = new byte[1024]; * var lengthReceived = client.GetStream().Read(bytesReceived, 0, bytesReceived.Length); * if (lengthReceived > 0) * { * var message = encoding.GetString(bytesReceived, 0, lengthReceived); * System.Console.WriteLine(MiniNet.Buffers.Buffer.DumpHex(bytesReceived, 0, lengthReceived, int.MaxValue)); * System.Console.WriteLine("'" + message + "'" + lengthReceived); * }*/ writer.Write("Client: Hello Server"); } Thread.Sleep(100); System.Console.WriteLine("Press ENTER to quit"); System.Console.ReadLine(); client.Close(); } } } catch (Exception ex) { System.Console.WriteLine(ex.ToString()); System.Console.WriteLine(ex.StackTrace); } }