我正在Windows 8 Consumer Preview中編寫Metro應用程序。如何在Windows 8 Consumer Preview中使用TcpClient
但是,我無法在.NET 4.5中使用TcpClient,似乎沒有地方可以添加程序集引用。
http://msdn.microsoft.com/en-us/library/1612451t(v=vs.110).aspx
我正在Windows 8 Consumer Preview中編寫Metro應用程序。如何在Windows 8 Consumer Preview中使用TcpClient
但是,我無法在.NET 4.5中使用TcpClient,似乎沒有地方可以添加程序集引用。
http://msdn.microsoft.com/en-us/library/1612451t(v=vs.110).aspx
TcpClient的是不支持地鐵側。您可以改爲使用StreamSocket類。 Here是如何使用它來創建一個TCP套接字,建立連接,發送和接收數據的示例。這些示例使用JS和C++,但相同的類將適用於C#。
最終,我們應該使用新的Metro NET的東西。但是,如果移植大量代碼並取決於您使用的TcpClient成員的多少,那麼只需在Metro對象周圍創建有限的實現可能並不是那麼糟糕。我想快速地將一堆代碼快速移植到Metro上(只是爲了試用一些東西),所以我打了一些似乎可行的東西,但絕大多數並不理想。 (你最終做的也就是通常所不齒異步方法的一些同步ING)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
namespace MetroNetHelper
{
public class IPAddress // assumes IPv4 currently
{
public string IP_String;
public IPAddress() { }
public IPAddress(string IP) { IP_String = IP; }
public static IPAddress Broadcast { get { return new IPAddress("255.255.255.255"); } }
public static IPAddress Parse(string IP) { return new IPAddress(IP); }
public static bool TryParse(string V, out IPAddress Addr)
{
try
{
Addr = IPAddress.Parse(V);
return true;
}
catch { Addr = null; return false; }
}
public HostName GetHostNameObject() { return new HostName(IP_String); }
public byte[] GetAddressBytes()
{
string[] Fields = IP_String.Split('.');
byte[] temp = new byte[4];
for (int i = 0; i < temp.Length; i++) temp[i] = byte.Parse(Fields[i]);
return temp;
}
}
public class IPEndPoint
{
public IPAddress Address;
public int Port;
public IPEndPoint() { }
public IPEndPoint(IPAddress Addr, int PortNum)
{
Address = Addr; Port = PortNum;
}
}
public class NetworkStream
{
private DataReader Reader;
private DataWriter Writer;
public void Set(StreamSocket HostClient)
{
Reader = new DataReader(HostClient.InputStream);
Reader.InputStreamOptions = InputStreamOptions.Partial;
Writer = new DataWriter(HostClient.OutputStream);
}
public int Write(byte[] Buffer, int Offset, int Len)
{
if (Offset != 0 || Len != Buffer.Length) throw new ArgumentException("Can only write whole byte array");
Writer.WriteBytes(Buffer);
Task Tk = Writer.StoreAsync().AsTask();
Tk.Wait();
return Buffer.Length;
}
public int Read(byte[] Buffer, int Offset, int Len)
{
if (Offset != 0 || Len != Buffer.Length) throw new ArgumentException("Can only read whole byte array");
Task<uint> Tk = Reader.LoadAsync((uint)Len).AsTask<uint>();
Tk.Wait();
uint Count = Tk.Result;
for (int i=0;i<Count;i++)
{
Buffer[i] = Reader.ReadByte();
}
return (int)Count;
}
public bool DataAvailable
{
get
{
return true; // Read() will still work if no data; could we do read ahead 1 byte to determine?
}
}
}
public class TcpClient
{
private StreamSocket sock;
public void Connect(IPEndPoint EndPt)
{
try
{
sock = new StreamSocket();
HostName Hst = EndPt.Address.GetHostNameObject();
Task Tsk = sock.ConnectAsync(Hst, EndPt.Port.ToString()).AsTask();
Tsk.Wait();
}
catch (Exception ex) { MetroHelpers.UnpeelAggregate(ex); }
}
public void Close()
{
sock.Dispose();
sock = null;
}
public NetworkStream GetStream()
{
var N = new NetworkStream();
N.Set(sock);
return N;
}
}
public static class MetroHelpers
{
public static void UnpeelAggregate(Exception Ex)
{
AggregateException Ag_Ex = Ex as AggregateException;
if (Ag_Ex == null) throw Ex;
if (Ag_Ex.InnerExceptions.Count > 0)
{
if (Ag_Ex.InnerExceptions.Count == 1) throw Ag_Ex.InnerExceptions[0];
StringBuilder Str = new StringBuilder();
foreach (Exception X in Ag_Ex.InnerExceptions)
{
Str.AppendLine(X.Message);
}
throw new Exception(Str.ToString(), Ag_Ex);
}
else throw Ag_Ex;
}
}
} // END NAMESPACE
這只是我做了快速和骯髒的早晨。如果它能幫助任何有想法的人,那就太棒再說一次,我們最好更好地開發微軟希望我們用於Metro應用程序的方式。當他們不斷改變紅潤的框架時,它變得令人沮喪。 (如果Xamarin可以在iOS/Android /等等上保持一致的框架,爲什麼不能在自己的操作系統中使用MS?)