public static void natnegCompleteCallback ( NatNegotiateResult result, IntPtr gamesocket, IntPtr remoteaddr, /*struct sockaddr_in * */ IntPtr userdata) { switch (result) { case NatNegotiateResult.nr_success: Console.WriteLine("NatNeg Result: Nat Negoation Success!"); break; case NatNegotiateResult.nr_deadbeatpartner: Console.WriteLine("NatNeg Result: nr_deadbeatpartner, The other machine isn't responding."); return; case NatNegotiateResult.nr_inittimeout: Console.WriteLine("NatNeg Result: nr_inittimeout, The NAT server could not be contacted."); return; case NatNegotiateResult.nr_pingtimeout: Console.WriteLine("NatNeg Result: nr_pingtimeout, The other machine could not be contacted."); return; default: Console.WriteLine("NatNeg Result: Nat Negoation Unknown error! %d", result); return; } if (result != NatNegotiateResult.nr_success) { return; } if (gamesocket != IntPtr.Zero) { Console.WriteLine("NatNeg Complete: Local game socket: {0}", gamesocket.ToString()); } if (remoteaddr != IntPtr.Zero) { gamespySocketIF.sockaddr_in remoteSockaddr = new gamespySocketIF.sockaddr_in(); remoteSockaddr = (gamespySocketIF.sockaddr_in)Marshal.PtrToStructure(remoteaddr, remoteSockaddr.GetType()); // IMPORTANT: remote sock port is in the network order. Convert to host order. // Unlike C, in C# the IP Address and Port conversion is transparent, done in the .Net Sockets ushort portno = (ushort)(IPAddress.NetworkToHostOrder((short)remoteSockaddr.sin_port)); IPAddress rIpAddr = new IPAddress(remoteSockaddr.sin_addr.S_addr); Console.WriteLine("NatNeg Got connected, Remote Address = {0} {1}:{2}", rIpAddr.AddressFamily, rIpAddr.ToString(), portno); remoteEndPoint.Address = rIpAddr; remoteEndPoint.Port = portno; connected = true; } }
public static void tryReadFrom(Socket sock) { System.Collections.IList readList = new List <Socket> (); readList.Add(sock); Socket.Select(readList, null, null, 0); EndPoint fromEndPoint = (EndPoint) new IPEndPoint(IPAddress.Any, 0); for (int i = 0; i < readList.Count; i++) { int length = 0; byte[] mybuffer = new byte[255]; try { length = sock.ReceiveFrom(mybuffer, ref fromEndPoint); } catch (Exception e) //(SocketException e) { Console.WriteLine("Exception: Problem connecting to host"); return; } Console.WriteLine("Local End Point {0}:{1} length {2}", IPAddress.Parse(((IPEndPoint)sock.LocalEndPoint).Address.ToString()), ((IPEndPoint)sock.LocalEndPoint).Port.ToString(), length); Console.WriteLine("Remote end point {0}:{1}", IPAddress.Parse(((IPEndPoint)fromEndPoint).Address.ToString()), ((IPEndPoint)fromEndPoint).Port.ToString()); if (length > 0) { int j = 0; for (; j < gamespyNatNeg.NATNEG_MAGIC_LEN && (mybuffer[j] == gamespyNatNeg.nnMagic[j]); j++) { ; } if (j == gamespyNatNeg.NATNEG_MAGIC_LEN) { gamespySocketIF.sockaddr_in saddr = new gamespySocketIF.sockaddr_in(); saddr.sin_addr.S_addr = (UInt32)((IPEndPoint)fromEndPoint).Address.Address; saddr.sin_family = (short)((IPEndPoint)fromEndPoint).AddressFamily; // IMPORTANT: Port has to be in network byte order. // we need to convert the network order since sockaddr_in expects in that order. short portNo = (short)(((IPEndPoint)fromEndPoint).Port); saddr.sin_port = (ushort)IPAddress.HostToNetworkOrder(portNo); Console.WriteLine("Received NAT Magic Bytes from {0}:{1}", ((IPEndPoint)fromEndPoint).Port, (System.Net.IPAddress.HostToNetworkOrder(((IPEndPoint)fromEndPoint).Port))); // Marshal sockaddr_in IntPtr remoteSockAddr = Marshal.AllocHGlobal(Marshal.SizeOf(saddr)); Marshal.StructureToPtr(saddr, remoteSockAddr, false); IntPtr mydata = Marshal.AllocHGlobal(length + 1); Marshal.Copy(mybuffer, 0, mydata, (length)); gamespyNatNeg.NNProcessData(mydata, length, remoteSockAddr); } else { StringBuilder recvStr = new StringBuilder(); ASCIIEncoding asciiString = new ASCIIEncoding(); recvStr.Append(asciiString.GetChars(mybuffer)); Console.WriteLine("Got Data ({0}:{1}) : {2}", IPAddress.Parse(((IPEndPoint)fromEndPoint).Address.ToString()), ((IPEndPoint)fromEndPoint).Port.ToString(), recvStr); } } } }