Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Silverlight中的异步套接字连接_C#_Silverlight_Sockets_Asynchronous_Tcp - Fatal编程技术网

C# Silverlight中的异步套接字连接

C# Silverlight中的异步套接字连接,c#,silverlight,sockets,asynchronous,tcp,C#,Silverlight,Sockets,Asynchronous,Tcp,我有TCP套接字服务器,并希望为其创建异步Silverlight客户端,但我找不到任何有用的信息。确切地说,我需要三个步骤:连接、发送和接收 不需要非常详细,只需要了解如何构建它以至少连接到服务器 顺便说一下,我使用Silverlight 5。非常感谢Karel Frajtak提供有关Silverlight中插座的视频链接! 视频教程中显示并解释了所有内容,因此我建议所有需要Silverlight中的插座的人观看! 以下是我需要的解决方案,包括解释什么是什么以及我的评论: 我假设所有连接操作都将

我有TCP套接字服务器,并希望为其创建异步Silverlight客户端,但我找不到任何有用的信息。确切地说,我需要三个步骤:连接、发送和接收

不需要非常详细,只需要了解如何构建它以至少连接到服务器


顺便说一下,我使用Silverlight 5。

非常感谢Karel Frajtak提供有关Silverlight中插座的视频链接! 视频教程中显示并解释了所有内容,因此我建议所有需要Silverlight中的插座的人观看! 以下是我需要的解决方案,包括解释什么是什么以及我的评论:

我假设所有连接操作都将由单独的类SocketConnection处理

public class MessageEventArgs : EventArgs
{
    public string Message { get; set; }
}
public class SocketConnection
{
    /// <summary>
    /// Event handler shot when message is received
    /// </summary>
    public event EventHandler<MessageEventArgs> MessageReceived;

    /// <summary>
    /// Socket used for connection to the server, sending and receiving data
    /// </summary>
    Socket socket;

    /// <summary>
    /// Default buffer size that should be used with the same value in both server and client
    /// </summary>
    int bufferSize = 128;

    /// <summary>
    /// Buffer used to store bytes received
    /// </summary>
    byte[] buffer;

    /// <summary>
    /// Bytes received in current receiving operation
    /// </summary>
    int bytesReceived;

    public SocketConnection(string host = "localhost", int port = 4502)
    {
        // Initializing buffer for receiving data
        buffer = new byte[bufferSize];
        // Initializing socket to connect to the server with default parameters
        // *** If you need IPv6, set the AddressFamily.InterNetworkV6 ***
        // *** Silverlight supports only Stream or Unknown socket types (Silverlight 5) ***
        // *** The only defined protocol supported by Silverlight is TCP.
        //     Others can be only Unknown or Unspecified (Silverlight 5)***
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        // Socket args that are needed for connection
        SocketAsyncEventArgs args = new SocketAsyncEventArgs()
        {
            // Server IP and port
            RemoteEndPoint = new DnsEndPoint(host, port),
            // If policy server is hosted as TCP socket, this has to be set to SocketClientAccessPolicyProtocol.Tcp
            // If policy is stored in HTTP server, this has to be set SocketClientAccessPolicyProtocol.Http
            SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Tcp
        };
        // Set the event handler for completed connection (nomatter if it is successful or not)
        args.Completed += OnConnected;
        // Start connecting to the server asynchronously
        socket.ConnectAsync(args);
    }

    /// <summary>
    /// Even handler shot when socket connection is completed
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void OnConnected(object sender, SocketAsyncEventArgs e)
    {
        // If the connection is not successful, set socket object to null
        if (e.SocketError != SocketError.Success)
        {
            if (e.SocketError == SocketError.AccessDenied)
            {
                // Policy server is not running or cannot be reached
                throw new SocketException((int)SocketError.AccessDenied);
            }
            socket = null;
        }
        // Begin receiving data otherwise
        else
        {
            BeginRead();
        }
    }

    /// <summary>
    /// Method for receiving data from the server
    /// </summary>
    private void BeginRead()
    {
        // Receive data only if socket is connected
        if (socket != null && socket.Connected)
        {
            SocketAsyncEventArgs args = new SocketAsyncEventArgs();
            // Store the received buffer in a class variable
            args.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived);
            // Set the event handler for received data
            args.Completed += OnReceived;

            // Start receiving data asynchronously
            socket.ReceiveAsync(args);
        }
    }

    /// <summary>
    /// Event handler shot when data is received from the server
    /// </summary>
    void OnReceived(object sender, SocketAsyncEventArgs e)
    {
        // Make sure that receiving was successful
        if (e.SocketError == SocketError.Success)
        {
            // Increase the count of received bytes in the current receiving operation
            bytesReceived += e.BytesTransferred;
        }
        // If the receiving was unsuccessful, throw an exception
        else
        {
            throw new SocketException();
        }
        // Check if the buffer is already full
        if (bytesReceived == buffer.Length)
        {
            // If the buffer is full, decode the string received from bytes
            // *** This should be your object deserialization, if you use anything but string ***
            string text = Encoding.UTF8.GetString(buffer, 0, buffer.Length);

            // If the event was set from somewhere, shoot it
            // *** In most cases event is set from UI thread to handle the
            //     received string or object and show the result to user ***
            if (MessageReceived != null)
            {
                // Shoot the event, if it's set
                MessageReceived(this, new MessageEventArgs()
                {
                    Message = text
                });
            }

            // Set the bytes received count to 0, for other data receiving event to fill the buffer from begining
            bytesReceived = 0;
        }
        // Begin the data receiving again
        BeginRead();
    }

    /// <summary>
    /// Sample method to send data to the server
    /// </summary>
    /// <param name="text">Text you would like the server to receive</param>
    public void SendText(string text)
    {
        // Check if the socket is connected to the server
        if (socket != null && socket.Connected)
        {
            // Encode the string to be sent to bytes
            // *** This is where your object serialization should be done ***
            byte[] buffer = Encoding.UTF8.GetBytes(text);
            // Check if the buffer is not empty
            if (buffer.Length != 0)
            {
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                // Set the buffer to be sent
                args.SetBuffer(buffer, 0, buffer.Length);

                // Start sending buffer to the server asynchronously
                socket.SendAsync(args);
            }
        }
    }
}
公共类MessageEventArgs:EventArgs
{
公共字符串消息{get;set;}
}
公共类SocketConnection
{
/// 
///收到消息时事件处理程序快照
/// 
已接收公共事件事件处理程序消息;
/// 
///用于连接服务器、发送和接收数据的套接字
/// 
插座;
/// 
///服务器和客户端中应使用相同值的默认缓冲区大小
/// 
int bufferSize=128;
/// 
///用于存储接收字节的缓冲区
/// 
字节[]缓冲区;
/// 
///在当前接收操作中接收的字节数
/// 
接收到int字节;
公共SocketConnection(string host=“localhost”,int-port=4502)
{
//初始化用于接收数据的缓冲区
buffer=新字节[bufferSize];
//正在初始化套接字以使用默认参数连接到服务器
//***如果需要IPv6,请设置AddressFamily.InterNetworkV6***
//***Silverlight仅支持流或未知套接字类型(Silverlight 5)***
//***Silverlight支持的唯一定义协议是TCP。
//其他只能是未知或未指定的(Silverlight 5)***
套接字=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp);
//连接所需的套接字参数
SocketAsyncEventArgs args=新的SocketAsyncEventArgs()
{
//服务器IP和端口
RemoteEndPoint=新的DnsEndPoint(主机、端口),
//如果策略服务器作为TCP套接字托管,则必须将其设置为SocketClientAccessPolicyProtocol.TCP
//如果策略存储在HTTP服务器中,则必须将其设置为SocketClientAccessPolicyProtocol.HTTP
SocketClientAccessPolicyProtocol=SocketClientAccessPolicyProtocol.Tcp
};
//设置已完成连接的事件处理程序(无论成功与否)
参数已完成+=未连接;
//开始异步连接到服务器
socket.ConnectAsync(args);
}
/// 
///当套接字连接完成时,即使处理程序也会被触发
/// 
/// 
/// 
连接无效(对象发送方,SocketAsyncEventArgs e)
{
//如果连接不成功,请将套接字对象设置为null
如果(例如SocketError!=SocketError.Success)
{
如果(e.SocketError==SocketError.AccessDenied)
{
//策略服务器未运行或无法访问
抛出新的SocketException((int)SocketError.AccessDenied);
}
socket=null;
}
//以其他方式开始接收数据
其他的
{
开始();
}
}
/// 
///从服务器接收数据的方法
/// 
私有的无效开始()
{
//仅在连接套接字时接收数据
if(socket!=null&&socket.Connected)
{
SocketAsyncEventArgs args=新的SocketAsyncEventArgs();
//将接收到的缓冲区存储在类变量中
args.SetBuffer(buffer,bytesReceived,buffer.Length-bytesReceived);
//设置接收数据的事件处理程序
args.Completed+=OnReceived;
//开始异步接收数据
socket.ReceiveAsync(args);
}
}
/// 
///从服务器接收数据时事件处理程序快照
/// 
收到时无效(对象发送方,SocketAsyncEventArgs e)
{
//确保接收成功
如果(e.SocketError==SocketError.Success)
{
//增加当前接收操作中接收的字节数
bytesReceived+=e.ByTestTransfered;
}
//如果接收失败,则引发异常
其他的
{
抛出新的SocketException();
}
//检查缓冲区是否已满
if(bytesReceived==buffer.Length)
{
//如果缓冲区已满,则对从字节接收的字符串进行解码
//***如果不使用字符串,则这应该是对象反序列化***
string text=Encoding.UTF8.GetString(buffer,0,buffer.Length);
//如果事件是从某处设置的,那么就拍摄它
//***在大多数情况下,从UI线程设置事件以处理
//接收到字符串或对象,并向用户显示结果***
if(MessageReceived!=null)
{
//拍摄该赛事,如果已经安排好的话
MessageReceived(这是新的MessageEventArgs()
{
消息=文本
});
}
//将接收的字节数设置为0,以便其他数据接收事件从一开始就填充缓冲区
字节数=0;
}
//再次开始数据接收
开始();
}
/// 
///将数据发送到服务器的示例方法
/// 
///您希望服务器接收的文本
公共void SendText(字符串文本)
{
//检查插座是否处于连接状态
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace PolicyServer
{
    // Encapsulate and manage state for a single connection from a client
    class PolicyConnection
    {
        private Socket _connection;
        private byte[] _buffer; // buffer to receive the request from the client       
        private int _received;
        private byte[] _policy; // the policy to return to the client

        // the request that we're expecting from the client
        private static string _policyRequestString = "<policy-file-request/>";

        public PolicyConnection(Socket client, byte[] policy)
        {
            _connection = client;
            _policy = policy;

            _buffer = new byte[_policyRequestString.Length];
            _received = 0;

            try
            {
                // receive the request from the client
                _connection.BeginReceive(_buffer, 0, _policyRequestString.Length, SocketFlags.None,
                    new AsyncCallback(OnReceive), null);
            }
            catch (SocketException)
            {
                _connection.Close();
            }
        }

        // Called when we receive data from the client
        private void OnReceive(IAsyncResult res)
        {
            try
            {
                _received += _connection.EndReceive(res);

                // if we haven't gotten enough for a full request yet, receive again
                if (_received < _policyRequestString.Length)
                {
                    _connection.BeginReceive(_buffer, _received, _policyRequestString.Length - _received,
                        SocketFlags.None, new AsyncCallback(OnReceive), null);
                    return;
                }

                // make sure the request is valid
                string request = System.Text.Encoding.UTF8.GetString(_buffer, 0, _received);
                if (StringComparer.InvariantCultureIgnoreCase.Compare(request, _policyRequestString) != 0)
                {
                    _connection.Close();
                    return;
                }

                // send the policy
                Console.Write("Sending policy...\n");
                _connection.BeginSend(_policy, 0, _policy.Length, SocketFlags.None,
                    new AsyncCallback(OnSend), null);
            }
            catch (SocketException)
            {
                _connection.Close();
            }
        }

        // called after sending the policy to the client; close the connection.
        public void OnSend(IAsyncResult res)
        {
            try
            {
                _connection.EndSend(res);
            }
            finally
            {
                _connection.Close();
            }
        }
    }

    // Listens for connections on port 943 and dispatches requests to a PolicyConnection
    class PolicyServer
    {
        private Socket _listener;
        private byte[] _policy;

        // pass in the path of an XML file containing the socket policy
        public PolicyServer(string policyFilePath)
        {

            // Load the policy file
            FileStream policyStream = new FileStream(policyFilePath, FileMode.Open);

            _policy = new byte[policyStream.Length];
            policyStream.Read(_policy, 0, _policy.Length);
            policyStream.Close();


            // Create the Listening Socket
            _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                ProtocolType.Tcp);

            _listener.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)
                SocketOptionName.NoDelay, 0);

            _listener.Bind(new IPEndPoint(IPAddress.Any, 943));
            _listener.Listen(10);

            _listener.BeginAccept(new AsyncCallback(OnConnection), null);
        }

        // Called when we receive a connection from a client
        public void OnConnection(IAsyncResult res)
        {
            Socket client = null;

            try
            {
                client = _listener.EndAccept(res);
            }
            catch (SocketException)
            {
                return;
            }

            // handle this policy request with a PolicyConnection
            PolicyConnection pc = new PolicyConnection(client, _policy);

            // look for more connections
            _listener.BeginAccept(new AsyncCallback(OnConnection), null);
        }

        public void Close()
        {
            _listener.Close();
        }
    }

    public class Program
    {
        static void Main()
        {
            Console.Write("Starting...\n");
            PolicyServer ps =
                new PolicyServer(@".\clientaccesspolicy.xml");
            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
        }
    }
}