1

TCPClient と NetworkStream が Silverlight にないのはなぜですか?
TCPClient と NetworkStream の Silverlight への既知のポートはありますか?
存在しない場合、ソース コードを .NET 4 ランタイムから自分のライブラリにコピーすることはできますか?
そうでない場合、これらのクラスを Silverlight に移植するにはどうすればよいですか?

4

2 に答える 2

2

Silverlight のネットワークにはかなりの制限があります。主に、Silverlight がブラウザーのサンドボックスで実行されるという事実に関連しています (たとえば、クロス ドメイン ポリシー、ポート制限など、緩和されたセキュリティ モデルで OOB アプリケーションを使用することで部分的に解決できます)。 )。

ただし、Silverlight はSocketsのサポートを提供しており、このような高レベルのクライアント実装がいくつかあります。

.NET 4 ランタイム ライセンスには、ソース コードを fork する権利は含まれておらず、Silverlight に移植する権利さえ含まれていないため、これらは独自のポートの構築を開始するための優れた基盤となる可能性があります。

于 2011-04-10T13:25:42.757 に答える
1

この質問は古いことは知っていますが、私にとっては非常に役に立ちました。jCoderに感謝します。リンクされた記事に基づいて実際にソリューションを作成しました。 http://weblogs.asp.net/mschwarz/archive/2008/03/07/silverlight-2-and-sockets.aspx

いくつかの変更を加えました。最も注目すべきは、送信と受信で作成された ScoketAsyncEventArgs を破棄することで解決した TcpClient にメモリ リークがあることです。ここにはもっと良い方法があるかもしれませんが、うまくいったので探すのをやめました。これがないと、イベントにサブスクライブすることで参照が保持されるようです。提案のために開きます。

私はこれを BinaryReader と BinaryWriter でのみ使用しました。マイレージは他のリーダーによって異なる場合があります。

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace IBApi
{
    public class TcpClientSl
    {
      private const int Receive = 1;
      private const int Send = 0;

      private bool isConnected = false;

      private Socket socket;
      private DnsEndPoint endPoint;
      public NotifyStream socketStream;

      private static AutoResetEvent autoEvent = new AutoResetEvent(false);
      private static AutoResetEvent autoSendEvent = new AutoResetEvent(false);
      private static AutoResetEvent autoReceiveEvent = new AutoResetEvent(false);

      NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        public TcpClientSl(string host, int port)
        {
          logger.Trace("TcpClientSl(string {0}, int {1})", host, port);

          endPoint = new DnsEndPoint(host, port, AddressFamily.InterNetwork);

          socket = new Socket(AddressFamily.InterNetwork 
                      /* hostEndPoint.AddressFamily */, 
                      SocketType.Stream, ProtocolType.Tcp);
          socketStream = new NotifyStream();
          socketStream.OnRead = ReadDelegate;
          socketStream.OnWrite = WriteDelegate;
        }

        int ReadDelegate (byte[] buffer, int offset, int count)
        {
          //logger.Trace("ReadDelegate (byte[] buffer, int {0}, int {1})", offset, count);
            // Prepare receiving.
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            args.SetBuffer(buffer, 0, buffer.Length);
            args.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
            socket.ReceiveAsync(args);
            if (!autoReceiveEvent.WaitOne(TimeSpan.FromMinutes(5)))
            {
              logger.Error("Receive Timeout");
              //this.Disconnect();
            }
            args.Dispose();
            return args.BytesTransferred;
        }

        void WriteDelegate(byte[] buffer, int offset, int count)
        {
          //logger.Trace("WriteDelegate(byte[] buffer, int {0}, int {1})", offset, count);
          if (isConnected && socket.Connected)
          {
              SocketAsyncEventArgs args = new SocketAsyncEventArgs();
              args.SetBuffer(buffer, offset, count);
              args.UserToken = socket;
              args.RemoteEndPoint = endPoint;
              args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);

              socket.SendAsync(args);

              if (!autoSendEvent.WaitOne(TimeSpan.FromMinutes(1)))
              {
                logger.Error("Send Timeout");
                //this.Disconnect();
              }
              args.Dispose();
          }
          else
              throw new SocketException((int)SocketError.NotConnected);
        }

        public void Connect()
        {

          logger.Trace("Connect()");
          SocketAsyncEventArgs args = new SocketAsyncEventArgs();

          args.UserToken = socket;
          args.RemoteEndPoint = endPoint;
          args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);

          socket.ConnectAsync(args);
          autoEvent.WaitOne();

          if (args.SocketError != SocketError.Success)
              throw new SocketException((int)args.SocketError);
        }

        public void Disconnect()
        {
          logger.Trace("Disconnect()");
          socket.Close();
        }

        #region Events

        private void OnConnect(object sender, SocketAsyncEventArgs e)
        {
          logger.Trace("OnConnect");
          autoEvent.Set();
          isConnected = (e.SocketError == SocketError.Success);
        }

        private void OnReceive(object sender, SocketAsyncEventArgs e)
        {
          //logger.Trace("OnReceive {0} bytes", e.BytesTransferred);
          if (e.BytesTransferred > 0)
          {
            autoReceiveEvent.Set();
          }
        }

        private void OnSend(object sender, SocketAsyncEventArgs e)
        {
          //logger.Trace("OnSend Bytes={0}", e.BytesTransferred);

          autoSendEvent.Set();

          if (e.SocketError == SocketError.Success)
          {
              if (e.LastOperation == SocketAsyncOperation.Send)
              {
              }
          }
          else
          {
              ProcessError(e);
          }
        }

        #endregion

        private void ProcessError(SocketAsyncEventArgs e)
        {
          logger.Trace("ProcessError");
          Socket s = e.UserToken as Socket;
          if (s.Connected)
          {
              try
              {
                  s.Shutdown(SocketShutdown.Both);
              }
              catch (Exception)
              {
              }
              finally
              {
                  if (s.Connected)
                      s.Close();
              }
          }

          throw new SocketException((int)e.SocketError);
        }

        #region IDisposable Members

        public void Dispose()
        {
          logger.Trace("Dispose");
          autoEvent.Close();
          autoSendEvent.Close();
          autoReceiveEvent.Close();
          if (socket.Connected)
              socket.Close();
        }

        #endregion
    }
}
于 2014-07-11T17:51:05.123 に答える