爲什麼Silverlight中缺少TCPClient和NetworkStream?
有沒有TCPClient和NetworkStream到Silverlight的任何已知端口?
如果沒有,我是否允許將源代碼從.NET 4運行時複製到我自己的庫中?
如果不是,我該如何開始將這些類移植到Silverlight?如何將TCPClient和NetworkStream端口連接到Silverlight?
1
A
回答
2
Networking in Silverlight有很多限制,主要與Silverlight在瀏覽器中的沙箱中運行有關(例如,跨域策略,端口限制等),部分可以通過使用OOB應用程序來解決安全模型)。
但是,Silverlight爲Sockets提供了一些支持,並且在那裏有一些高級客戶端實現,如this one。
這些可能是開始構建自己的端口的一個很好的基礎,因爲我認爲.NET 4運行時許可證不包括分叉源代碼的權利,甚至不會將它們移植到Silverlight。
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
}
}
相關問題
- 1. 如何使用.NET NetworkStream和TcpClient連接到遠程IP並等待數據?
- 2. TcpClient;的NetworkStream; ReadAsync; C#
- 3. 使用TcpClient連接到端點時遇到問題,其中端口> 8000
- 4. 將Silverlight連接到本地計算機COM端口
- 5. TCPClient和TCPListener - NetworkStream - 消息順序
- 6. TcpClient的NetworkStream不會收到每個包
- 7. 是否需要關閉NetworkStream和TcpClient,或只是TcpClient?
- 8. TCPClient連接到IP列表
- 9. 如何從android連接到localhost端口?
- 10. TcpClient不連接
- 11. TcpClient的連接
- 12. 獲取連接的TcpClient的遠程端口
- 13. 如何從端口80到端口XXXX無縫連接/轉發?
- 14. 連接到端口和授權
- 15. 如何連接Open vSwitch端口和虛擬以太網接口?
- 16. 使用iptables將端口80連接到端口5000
- 17. 如果Tcpclient無法連接
- 18. 套接字接收相當於上的NetworkStream/TcpClient的
- 19. 動態更改TCPClient端口
- 20. TcpClient連接錯誤
- 21. TcpClient連接延遲
- 22. 如何在Silverlight中將端口打開回80端口?
- 23. 如何連接到特定的IP和端口在android
- 24. TcpClient的超時對比的NetworkStream超時
- 25. 存儲用於廣播的TcpClient或NetworkStream?
- 26. 關閉TcpClient及其底層NetworkStream
- 27. Http 1.1連接和客戶端端口
- 28. Tcpclient多個客戶端連接到服務器
- 29. C#配置TCPClient客戶端的端口
- 30. TCPClient將不會連接自定義類
感謝但注意到第一個問題。他們爲什麼失蹤? – 2011-04-11 09:10:31
我想WCF/WebService,HttpWebRequest,WebClient的集成在第一個版本中似乎是「足夠」的,而低級聯網後來被開發人員要求時,限制變得更加令人沮喪。但我想只有Silverlight開發團隊將對你的問題的這一部分有100%的答案;) – jCoder 2011-04-11 16:09:49