Do you have any experience in "socket color change? As one of my friends said, socket is a last resort. Haha, is socket really so scary?
In fact, this is not false. Sometimes the socket is really not very easy to manipulate and maintain, but in any case, we still need to face it, maybe the socket is a big beauty.
I don't need to go into detail about socket's past and present lives. Many people have written about her history, such as our domestic Baidu encyclopedia and interactive encyclopedia; the world's most famous word, such as Wikipedia. In addition, if you can join WP development, I think you will certainly have a certain foundation for other. NET technologies. I also believe that my colleagues have written programs dealing with sockets in the past. So what about the socket in WP?
The answer should be posted on the premise. Using socket in WP is the same as that in other desktop application projects such as winform and WPF, the socket in WP is inherited from the Silverlight framework.
. One of the major advantages of net is that the integration and uniformity are good. No, you see, whether you are writing desktop applications or applications on WP, you will find that, your learning cost is not high. Many things are the same and the same. Obviously, this is why Win8 and WP8 applications can be integrated.
Pay attention to the following points when using socket in WP:
1. WP client applications are generally not considered as servers, because local endpoints and listener Connections cannot be bound. However, sending and receiving data is okay. D.
2. socket operations (connections, receives, and sends) in WP are asynchronous. If you want to synchronize the UI thread with the back-end thread, you can use the system. Threading. manualresetevent class. This is not easy to tell or understand. Let me give you an example.
One day, the NC and the brain are in conflict with each other because of a small matter. What should I do? As a result, NC and mentally handicapped decided to have a comparison. The two agreed to compete in running mode. Whoever runs fast is the winner. However, the NC person is at your own risk, and he believes that his brain will never run over him. In this way, NC modifies the competition rules:
NC allows the brain to run for five seconds before it starts.
Assume that NC is the main thread, and the brain is the background thread. The current situation is that the main thread waits for a while to let the background thread execute first, and the background thread sends a signal to the main thread after 5 seconds, the main thread continues to execute after receiving the signal. According to the plot in the story: NC first let the brain run for five seconds, and he waited on the starting line. After the brain ran for five seconds, he sent a signal to NC. After seeing the signal, NC started to run.
The following describes a class, socketasynceventargs.
This class is a parameter passed when an asynchronous operation is started. It can contain data receiving buffers, remote hosts, user-defined objects, and so on. This class is not complex, open "Object Browser" and you will see it at a glance.
To set a buffer for asynchronous data receiving, call the setbuffer method.
Well, there is no new knowledge point in theory. I just want to mention it briefly.
According to the Convention, everyone will know what to do after the theory, yes, and put it into practice.
In many cases, a chat program is used for socket examples. However, the chat program requires both the server side and the customer to have the function of sending and receiving data, this will increase the difficulty of the instance and the length of the Code, which is not easy for beginners to read. So I thought for a moment. Today we don't play chatting. Today we are playing remote control planes. What should we do?
The program code is too long to be explained one by one. In this case, I will paste the complete code to keep the code readable and add comments in the Code as appropriate.
Let's talk about the principle first. Using socket for Communication doesn't need to be said. That's for sure. The function uses the WP mobile client application to control the playback, pause, and stop animation on the PC end. However, the animation is not so complicated, let's get an animation that moves the rectangle from the left to the right.
Part 1 Server
Since you want to play an animation, you must use WPF. Besides, you can easily paste the code of the interface layout.
1. Create a WPF application project.
2. Open the mainwindow. XAML file (which is automatically opened after the project is created by default) and enter the following XAML code.
<Window X: class = "myserver. mainwindow "xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "Title =" server side "Height =" 350 "width =" 525 "> <window. resources> <storyboard X: Key = "STD"> <doubleanimation duration = "0: 0: 5" storyboard. targetname = "rect" storyboard. targetproperty = "(rectangle. rendertransform ). (translatetransform. x) "to =" 400 "/> </storyboard> </window. resources> <grid. rowdefinitions> <rowdefinition/> <rowdefinition Height = "Auto"/> </grid. rowdefinitions> <rectangle X: Name = "rect" grid. row = "0" width = "50" Height = "50" fill = "orange" horizontalalignment = "Left" verticalalignment = "center"> <rectangle. rendertransform> <translatetransform x = "0" Y = "0"/> </rectangle. rendertransform> </rectangle> <textblock name = "txtdisplay" grid. row = "1"/> </GRID> </WINDOW>
3. Open the mainwindow. XAML. CS file to complete the background code logic.
Using system; using system. collections. generic; using system. LINQ; using system. text; using system. windows; using system. windows. controls; using system. windows. data; using system. windows. documents; using system. windows. input; using system. windows. media; using system. windows. media. imaging; using system. windows. navigation; using system. windows. shapes; using system. windows. media. animation; using system. io; using system. net; using system. net. sockets; namespace myserver {// <summary> // mainwindow. interaction logic of XAML // </Summary> Public partial class mainwindow: window {storyboard STD = NULL; // Demo Board Public mainwindow () {initializecomponent (); // read the storyboard with the key as STD from the resource. STD = This. resources ["STD"] As storyboard; // declare Socket socket server = new socket (addressfamily. interNetwork, sockettype. stream, protocoltype. TCP); ipendpoint local = new ipendpoint (IPaddress. any, 1377); // listen to the address server on all network interfaces. BIND (local); // bind the local endpoint server. listen (100); // listen for connection requests // start to asynchronously accept the incoming connection request server. beginaccept (New asynccallback (this. acceptsocketcallback), server) ;}/// <summary> // receives the callback of the incoming socket /// </Summary> private void acceptsocketcallback (iasyncresult IA) {socket _ socket = IA. asyncstate as socket; socket accptsocket = _ socket. endaccept (IA); try {ipendpoint remote = (ipendpoint) accptsocket. remoteendpoint; // display the client's IP address dispatcher. begininvoke (new action <string> (this. setipfortext), remote. address. tostring (); stateobject so = new stateobject (); so. thesocket = accptsocket; // start receiving messages asynchronously. beginreceive (SO. buffer, 0, so. buffer. length, socketflags. none, new asynccallback (this. receivecallback), so);} catch {} // continue to accept connection request_socket. beginaccept (New asynccallback (this. acceptsocketcallback), _ socket) ;}/// <summary> /// callback for receiving messages /// </Summary> private void receivecallback (iasyncresult IA) {stateobject _ SO = IA. asyncstate as stateobject; socket _ socket = _ SO. thesocket; try {int n = _ socket. endreceive (IA); // n indicates the number of bytes received. String MSG = encoding. utf8.getstring (_ SO. buffer, 0, n); // determines the command switch (MSG) {Case "play": Dispatcher sent by the client. begininvoke (new action (this. play), null); break; Case "pause": dispatcher. begininvoke (new action (this. pause), null); break; Case "stop": dispatcher. begininvoke (new action (this. stop), null); break; default: break;} catch {} _ SO = new stateobject (); _ SO. thesocket = _ socket; // continue to receive the message _ socket. beginreceive (_ SO. buffer, 0, _ SO. buffer. length, socketflags. none, new asynccallback (this. export ecallback), _ SO);} // <summary> // display the Client IP address // </Summary> private void setipfortext (string IP) {this.txt display. TEXT = "Client IP:" + IP;} # region animation control method private void play () {STD. begin ();} private void pause () {STD. pause ();} private void stop () {STD. stop ();} # endregion} // <summary> // status object used for asynchronous socket operation delivery /// </Summary> public class stateobject {private const int buffer_size = 512; public byte [] buffer {Get; set;} public socket thesocket {Get; set ;} /// <summary> /// constructor /// </Summary> Public stateobject () {This. buffer = new byte [buffer_size] ;}}
Part 2 WP Client
1. Create a Windows Phone application project.
2. Open the mainpage. XAML file and refer to the following XAML code.
<Phone: phoneapplicationpage X: class = "wpclient. mainpage "xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation "xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "xmlns: Phone =" CLR-namespace: Microsoft. phone. controls; Assembly = Microsoft. phone "xmlns: shell =" CLR-namespace: Microsoft. phone. shell; Assembly = Microsoft. phone "xmlns: D =" http://schemas.microsoft.com/expression/blend/2008 "xmlns: MC =" Http://schemas.openxmlformats.org/markup-compatibility/2006 "MC: ignorable =" D "D: designwidth =" 480 "D: designheight = "768" fontfamily = "{staticresource quota}" fontsize = "{staticresource quota}" foreground = "{staticresource quota}" supportedorientations = "portrait" orientation = "portrait" Shell: systemtray. isvisible = "true"> <! -- Layoutroot is the root mesh that contains all page content --> <grid X: Name = "layoutroot" background = "Transparent"> <grid. rowdefinitions> <rowdefinition Height = "Auto"/> <rowdefinition Height = "*"/> </grid. rowdefinitions> <! -- Titlepanel contains the application name and page title --> <stackpanel X: Name = "titlepanel" grid. row = "0" margin = ","> <textblock X: name = "applicationtitle" text = "my application" style = "{staticresource phonetextnormalstyle}"/> <textblock X: name = "pagetitle" text = "Page name" margin = "9,-7,0, 0" style = "{staticresource phonetexttitle1style}"/> </stackpanel> <! -- Contentpanel-place other content here --> <grid X: Name = "contentpanel" grid. row = "1" margin = "12, 0, 12, 0"> <grid. rowdefinitions> <rowdefinition Height = "Auto"/> <rowdefinition Height = "*"/> </grid. rowdefinitions> <grid. row = "0"> <grid. columndefinitions> <columndefinition width = "Auto"/> <columndefinition width = "Auto"/> </grid. columndefinitions> <textblock grid. column = "0" verticalalignment =" Center "text =" Server IP: "/> <textbox name =" txtserverip "grid. column = "1"/> <button grid. column = "2" content = "Connect" Click = "onconnect"/> </GRID> <stackpanel grid. row = "1"> <button content = "play Animation" Click = "onplay"/> <button content = "Pause Animation" Click = "onpause"/> <button content = "Stop Animation" Click = "onstop"/> <textblock name = "txtbinfo" margin = "3,18, 3, 0 "/> </stackpanel> </GRID> <! -- DEMO code to demonstrate ApplicationBar usage --> <! -- <Phone: phoneapplicationpage. applicationBar> <shell: ApplicationBar isvisible = "true" ismenuenabled = "true"> <shell: applicationbariconbutton iconuri = "/images/appbar_button1.png" text = "button 1"/> <shell: applicationbariconbutton iconuri = "/images/appbar_button2.png" text = "button 2"/> <shell: ApplicationBar. menuitems> <shell: applicationbarmenuitem text = "menu item 1"/> <shell: applicationbarmenuitem text = "menu item 2"/> </shell: ApplicationBar. menuitems> </shell: ApplicationBar> </Phone: phoneapplicationpage. applicationBar> --> </Phone: phoneapplicationpage>
3. Open mainpage. XAML. CS and enter the following code.
Using system; using system. collections. generic; using system. LINQ; using system. net; using system. windows; using system. windows. controls; using system. windows. documents; using system. windows. input; using system. windows. media; using system. windows. media. animation; using system. windows. shapes; using Microsoft. phone. controls; using system. net. sockets; using system. io; using system. threading; namespace wpclient {Publ IC partial class mainpage: phoneapplicationpage {socket mysocket = NULL; manualresetevent myevent = NULL; // constructor public mainpage () {initializecomponent ();} protected override void onnavigatedto (system. windows. navigation. navigationeventargs e) {base. onnavigatedto (E); If (mysocket = NULL) {mysocket = new socket (addressfamily. interNetwork, sockettype. stream, protocoltype. TCP);} If (myevent = = NULL) {myevent = new manualresetevent (false) ;}} protected override void onnavigatedfrom (system. Windows. Navigation. navigationeventargs e) {If (mysocket! = NULL) {mysocket. shutdown (socketshutdown. both); mysocket. close ();} base. onnavigatedfrom (E);} private void onconnect (Object sender, routedeventargs e) {If (mysocket! = NULL) {socketasynceventargs connarg = new socketasynceventargs (); // the remote server connarg to be connected. remoteendpoint = new dnsendpoint(this.txt serverip. text, 1377); // The callback connarg after the operation is complete. completed + = (sendobj, ARG) => {If (Arg. socketerror = socketerror. success) // connection successful {dispatcher. begininvoke () => txtbinfo. TEXT = "connection successful. ");} Else {dispatcher. begininvoke () => {txtbinfo. TEXT = "connection failed, error:" + Arg. socketerror. tostring () ;}) ;}// report the operation to the calling thread to end myevent. set () ;}; // reset the thread wait event myevent. reset (); txtbinfo. TEXT = "connection in progress. Please wait ...... "; // Start an asynchronous connection to mysocket. connectasync (connarg); // wait for the connection to complete myevent. waitone (6000) ;}} private void onpause (Object sender, routedeventargs e) {sendcommand ("pause");} private void onstop (Object sender, routedeventargs E) {sendcommand ("stop");} private void onplay (Object sender, routedeventargs e) {sendcommand ("play");} private void sendcommand (string txt) {If (mysocket! = NULL & mysocket. connected) {socketasynceventargs sendarg = new socketasynceventargs (); byte [] buffer = system. text. encoding. utf8.getbytes (txt); sendarg. setbuffer (buffer, 0, buffer. length); // The sendarg callback after sending is complete. completed + = (objsender, Marg) => {// if the operation is successful if (marg. socketerror = socketerror. success) {dispatcher. begininvoke () => txtbinfo. TEXT = "sent successfully. ");} Else {dispatcher. begininvoke () => {this.txt binfo. TEXT = "failed to send, error:" + marg. socketerror. tostring () ;}) ;}// report that the asynchronous operation ends myevent. set () ;}; // reset the signal myevent. reset (); txtbinfo. TEXT = "sending... please wait ...... "; // Send mysocket. sendasync (sendarg) asynchronously; // wait until myevent. waitone (6000) is completed );}}}}
Run the server first, and then run the client on the WP simulator or mobile phone.
In the mobile client, enter the IP address and click "Connect". After the connection is successful, the command can be sent.
All right, let's go here. I will upload the sample source code to "resource". If you need it, you can download it by title.