For communication in Silverlight, data transmission can only be performed on ports between and, in addition, the Silverlight client automatically sends a "<policy-file-Request/>" Statement request to the server on port 943, then, port 943 on the server sends back the following files to permit socket communication.
<? XML version = " 1.0 " Encoding = " UTF-8 " ?> <Access-Policy> <cross-domain-access> <Policy> <allow- From > <Domain uri = " * " /> </Allow- From > <Grant-to> <socket-resource Port = " 4502-4534 " Protocol = " TCP " /> </Grant-to> </Policy> </Cross-Domain-access> </access-Policy>
A. Now let's first look at the server sideCode, Mainly divided into policy response steps and service response steps.
Step 1: Enable listening to port 943 for security policy file requests
Step 2: If the client request is <policy-file-Request/>, the security policy file is sent to the client as bytes.
Service Step 1: Start the server and listen to port 4525. Is there a socket conversation request?
Step 2: If there is a connection requested by the client, send a message to inform the client
The Code is as follows:
Class Program { Static Void Main ( String [] ARGs ){ // Policy Step 1: Start listening to port 943 to check whether security policy file requests are required Thread access = New Thread ( New Threadstart (accessthread); Access. Start (); // Service Step 1: Start the server and listen to port 4525. Is there a socket conversation request? Thread Server = New Thread ( New Threadstart (serverthread); server. Start ();} // Policy request listener Static Void Accessthread (){ // Obtain the socket server for port 943 listening Socket socket = getsocketserver ( 943 ); While (True ) {Socket new_access = Socket. Accept (); String Clientpolicystring = " <Policy-file-Request/> " ; Byte [] Requestbytes = New Byte [Clientpolicystring. Length]; new_access.receive (requestbytes ); String Requeststring = system. Text. encoding. utf8.getstring (requestbytes, 0 , Requestbytes. Length ); If (Requeststring = Clientpolicystring ){ // Policy Step 2: If the client request is <policy-file-Request/>, the security policy file is sent to the client as bytes. Byte [] Accpolicytes = Getpolicytoclient (); new_access.send (accessbytes, accessbytes. length, socketflags. None); new_access.close ();} thread. Sleep ( 100 );}} Static Void Serverthread (){ // Obtain the socket server for port 4525 listening Socket socket = getsocketserver ( 4525 ); While ( True ) {Socket _ socket = Socket. Accept (); // Service Step 2: If a client requests a connection, send a message to inform the client Byte [] B2 = New Byte [ 1024 ]; _ Socket. Receive (B2); console. writeline (encoding. utf8.getstring (B2). Replace ( " \ 0 " , "" )); String Recstring = " I have received the message. " ; _ Socket. Send (encoding. utf8.getbytes (recstring); _ socket. Close (); thread. Sleep ( 100 );}} // Establish a socket server based on the port Static Socket getsocketserver ( Int SERVERPORT) {Socket socket = New Socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP); socket. BIND ( New Ipendpoint (IPaddress. Any, SERVERPORT); socket. Listen ( 40 ); Return Socket ;} // Obtain the byte of the security policy file [] Static Byte [] Getpolicytoclient (){ String Path = environment. currentdirectory. Replace ( " \ Bin \ debug " , "" ); Filestream FS = New Filestream (path + @" \ Clientaccesspolicy. xml " , Filemode. Open ); Int Length = ( Int ) Fs. length; Byte [] Bytes = New Byte [Length]; FS. Read (bytes, 0 , Length); FS. Close (); Return Bytes ;}}
B. Next, let's look at the client operations in the following steps:
Client Step 1: Initiate a server connection request.
Step 2: The connection to the server is successful. Put the data to be sent into the buffer zone and send a message request to the server asynchronously.
Client step 3: The message is successfully sent. In this case, a new buffer instance is set and a message is asynchronously received from the server.
Client Step 4: Gets the message returned by the server and closes the socket.
The client CS code is as follows:
Public Partial Class Mainpage: usercontrol { Public Mainpage () {initializecomponent ();} system. net. sockets. Socket socket; Private Void Button#click ( Object Sender, routedeventargs e ){ Byte [] Userbytes = encoding. utf8.getbytes ( This . Tbinput. Text); socket = New System. net. sockets. socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP); socketasynceventargs socketargs = New Socketasynceventargs (); socketargs. remoteendpoint = New Dnsendpoint ( " 127.0.0.1 " , 4525 ); // Convert the content to byte [] and save it to the usertoken attribute. Socketargs. usertoken =Userbytes; socketargs. Completed + = New Eventhandler <socketasynceventargs> (Socketargs_completed ); // Client Step 1: Initiate a server connection request. Socket. connectasync (socketargs );} // This method is activated for each socket operation, including connect/send/receive/none) Void Socketargs_completed ( Object Sender, socketasynceventargs e ){ If (E. lastoperation = Socketasyncoperation. Connect ){ // Client Step 2: connect to the server successfully, put the data to be sent into the buffer, and then asynchronously send a message request to the server Byte [] Userbytes = ( Byte []) E. usertoken; E. setbuffer (userbytes, 0 , Userbytes. Length); socket. sendasync (E );} Else If (E. lastoperation =Socketasyncoperation. Send ){ // Client Step 3: the message is successfully sent. In this case, a new buffer instance is set and the server asynchronously receives the message returned by the server. Byte [] Userbytes = New Byte [ 1024 ]; E. setbuffer (userbytes, 0 , Userbytes. Length); socket. receiveasync (E );} Else If (E. lastoperation =Socketasyncoperation. Receive ){ // Client Step 4: get the message returned by the server and disable socket String Receviestr = encoding. utf8.getstring (E. buffer, 0 , E. Buffer. Length). Replace ( " \ 0 " , "" ); // Because it is an asynchronous socket request, you need to use the UI thread to update the Display Effect of lbshowmessage. This . Lbshowmessage. Dispatcher. begininvoke ( New Dothingdele (dothing), receviestr); socket. Close ();}} // Update the UI Public Void Dothing ( String Arg ){ This . Lbshowmessage. content = This . Lbshowmessage. content + " -> " +ARG ;} // A declared dothing method delegate Public Delegate Void Dothingdele ( String Arg );}
The front-end code of the client's XAML is as follows:
<Grid X: Name = " Layoutroot " Background = " White " Showgridlines =" True " > <Textbox Height = " 23 " Horizontalalignment = " Left " Margin = " 20, 20, 0, 0 " Name = " Tbinput " Verticalalignment = " Top " Width = " 243 " /> <Button content = " Send " Height = " 23 " Horizontalalignment = " Left " Margin = " 279,20, 0, 0 " Name = " Button1 " Verticalalignment = " Top " Width = " 75 " Click = " Button#click " /> <SDK: Label Height = " 28 " Horizontalalignment = " Left " Margin = " 20, 57, 0, 0 " Name = " Lbshowmessage " Verticalalignment =" Top " Width = " 358 " /> </GRID>
The final effect is as follows. If you need the source code, click slsocket.zip to download it. This article demonstrates the simplest communication effect: