Как использовать TcpClient в Windows 8 Consumer Preview

Я пишу приложение Metro в Windows 8 Consumer Preview.

Однако я не могу использовать TcpClient в .NET 4.5, кажется, нет места для добавления ссылки на сборку.

http://msdn.microsoft.com/en-us/library/1612451t(v=vs.110).aspx


person LB.    schedule 05.03.2012    source источник


Ответы (2)


TcpClient не поддерживается на стороне метро. Вы можете использовать класс StreamSocket. вместо. здесь приведен пример того, как использовать его для создания TCP-сокета, создания подключение, отправка и получение данных. Примеры представлены в JS и C++, но тот же класс будет работать и в C#.

person sarvesh    schedule 05.03.2012

В конце концов, нам, вероятно, следует использовать новый материал Metro NET. Однако при переносе большого количества кода и в зависимости от того, сколько членов TcpClient вы используете, может быть не так уж плохо просто создать ограниченную реализацию вокруг объектов Metro. Я хотел в спешке портировать кучу кода в Metro (просто чтобы попробовать кое-что), поэтому я собрал что-то вроде работающего, но уж точно не идеального. (В конечном итоге вы выполняете некоторую синхронизацию асинхронных методов, что обычно не одобряется.)

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 так, как хочет Microsoft. Это просто расстраивает, когда они продолжают менять румяный фреймворк. (Если Xamarin может поддерживать согласованные фреймворки на iOS/Android/и т. д., почему MS не может работать на своих собственных ОС!)

person CFD    schedule 26.04.2012